diff --git a/Cargo.lock b/Cargo.lock
index 69395bf281e8f17637cd70b32e328f8eaf21ff1d..4ee0dfdccff6b6019993584e023bce2f42623cf5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -820,17 +820,22 @@ dependencies = [
  "assert_matches",
  "asset-hub-rococo-runtime",
  "asset-test-utils",
+ "cumulus-pallet-parachain-system",
  "emulated-integration-tests-common",
  "frame-support",
  "pallet-asset-conversion",
  "pallet-assets",
  "pallet-balances",
  "pallet-message-queue",
+ "pallet-treasury",
+ "pallet-utility",
  "pallet-xcm",
  "parachains-common",
  "parity-scale-codec",
  "penpal-runtime",
+ "polkadot-runtime-common",
  "rococo-runtime",
+ "rococo-runtime-constants",
  "rococo-system-emulated-network",
  "sp-runtime",
  "staging-xcm",
@@ -2830,6 +2835,36 @@ dependencies = [
  "testnet-parachains-constants",
 ]
 
+[[package]]
+name = "collectives-westend-integration-tests"
+version = "1.0.0"
+dependencies = [
+ "assert_matches",
+ "asset-hub-westend-runtime",
+ "collectives-westend-runtime",
+ "cumulus-pallet-parachain-system",
+ "cumulus-pallet-xcmp-queue",
+ "emulated-integration-tests-common",
+ "frame-support",
+ "pallet-asset-rate",
+ "pallet-assets",
+ "pallet-balances",
+ "pallet-message-queue",
+ "pallet-treasury",
+ "pallet-utility",
+ "pallet-xcm",
+ "parachains-common",
+ "parity-scale-codec",
+ "polkadot-runtime-common",
+ "sp-runtime",
+ "staging-xcm",
+ "staging-xcm-executor",
+ "testnet-parachains-constants",
+ "westend-runtime",
+ "westend-runtime-constants",
+ "westend-system-emulated-network",
+]
+
 [[package]]
 name = "collectives-westend-runtime"
 version = "3.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 460c49f7f37c2d43e021e4bfa8f4263ac1ea3063..b3ae264bc3a40f70cb6ebeae67a5d144cb835fa1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -103,6 +103,7 @@ members = [
 	"cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend",
 	"cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo",
 	"cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend",
+	"cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend",
 	"cumulus/parachains/integration-tests/emulated/tests/people/people-rococo",
 	"cumulus/parachains/integration-tests/emulated/tests/people/people-westend",
 	"cumulus/parachains/pallets/collective-content",
diff --git a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs
index 379a29d697bcb564b670eadb638f7088f042137a..7a3a936ec972f0a8c99e3b472c7cce9e9914e29c 100644
--- a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs
@@ -39,6 +39,8 @@ decl_test_relay_chains! {
 			Hrmp: rococo_runtime::Hrmp,
 			Identity: rococo_runtime::Identity,
 			IdentityMigrator: rococo_runtime::IdentityMigrator,
+			Treasury: rococo_runtime::Treasury,
+			AssetRate: rococo_runtime::AssetRate,
 		}
 	},
 }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml
index c5a672234a0d21603c86b64af75adc57beffb81b..ddd6d2d049823f36ed193597ff438f39468a8a55 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml
@@ -21,15 +21,20 @@ pallet-balances = { path = "../../../../../../../substrate/frame/balances", defa
 pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false }
 pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false }
 pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue", default-features = false }
+pallet-treasury = { path = "../../../../../../../substrate/frame/treasury", default-features = false }
+pallet-utility = { path = "../../../../../../../substrate/frame/utility", default-features = false }
 
 # Polkadot
 xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false }
 pallet-xcm = { path = "../../../../../../../polkadot/xcm/pallet-xcm", default-features = false }
 xcm-executor = { package = "staging-xcm-executor", path = "../../../../../../../polkadot/xcm/xcm-executor", default-features = false }
 rococo-runtime = { path = "../../../../../../../polkadot/runtime/rococo" }
+polkadot-runtime-common = { path = "../../../../../../../polkadot/runtime/common" }
+rococo-runtime-constants = { path = "../../../../../../../polkadot/runtime/rococo/constants" }
 
 # Cumulus
 asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
+cumulus-pallet-parachain-system = { path = "../../../../../../pallets/parachain-system", default-features = false }
 parachains-common = { path = "../../../../../common" }
 asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
 penpal-runtime = { path = "../../../../../runtimes/testing/penpal" }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs
index 2402989225af2a6b3d03c7f353c8b0e7266b9fb1..346af30823848dc60363bb8011faa48be2b80d67 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs
@@ -19,3 +19,4 @@ mod send;
 mod set_xcm_versions;
 mod swap;
 mod teleport;
+mod treasury;
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs
new file mode 100644
index 0000000000000000000000000000000000000000..01bf40ae8fdf2cf87092c83ef604ef25427e2939
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs
@@ -0,0 +1,270 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::imports::*;
+use emulated_integration_tests_common::accounts::{ALICE, BOB};
+use frame_support::{
+	dispatch::RawOrigin,
+	sp_runtime::traits::Dispatchable,
+	traits::{
+		fungible::Inspect,
+		fungibles::{Create, Inspect as FungiblesInspect, Mutate},
+	},
+};
+use parachains_common::AccountId;
+use polkadot_runtime_common::impls::VersionedLocatableAsset;
+use rococo_runtime::OriginCaller;
+use rococo_runtime_constants::currency::GRAND;
+use xcm_executor::traits::ConvertLocation;
+
+// Fund Treasury account on Asset Hub from Treasury account on Relay Chain with ROCs.
+#[test]
+fn spend_roc_on_asset_hub() {
+	// initial treasury balance on Asset Hub in ROCs.
+	let treasury_balance = 9_000 * GRAND;
+	// the balance spend on Asset Hub.
+	let treasury_spend_balance = 1_000 * GRAND;
+
+	let init_alice_balance = AssetHubRococo::execute_with(|| {
+		<<AssetHubRococo as AssetHubRococoPallet>::Balances as Inspect<_>>::balance(
+			&AssetHubRococo::account_id_of(ALICE),
+		)
+	});
+
+	Rococo::execute_with(|| {
+		type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
+		type RuntimeCall = <Rococo as Chain>::RuntimeCall;
+		type Runtime = <Rococo as Chain>::Runtime;
+		type Balances = <Rococo as RococoPallet>::Balances;
+		type Treasury = <Rococo as RococoPallet>::Treasury;
+
+		// Fund Treasury account on Asset Hub with ROCs.
+
+		let root = <Rococo as Chain>::RuntimeOrigin::root();
+		let treasury_account = Treasury::account_id();
+
+		// Mint assets to Treasury account on Relay Chain.
+		assert_ok!(Balances::force_set_balance(
+			root.clone(),
+			treasury_account.clone().into(),
+			treasury_balance * 2,
+		));
+
+		let native_asset = Location::here();
+		let asset_hub_location: Location = [Parachain(1000)].into();
+		let treasury_location: Location = (Parent, PalletInstance(18)).into();
+
+		let teleport_call = RuntimeCall::Utility(pallet_utility::Call::<Runtime>::dispatch_as {
+			as_origin: bx!(OriginCaller::system(RawOrigin::Signed(treasury_account))),
+			call: bx!(RuntimeCall::XcmPallet(pallet_xcm::Call::<Runtime>::teleport_assets {
+				dest: bx!(VersionedLocation::V4(asset_hub_location.clone())),
+				beneficiary: bx!(VersionedLocation::V4(treasury_location)),
+				assets: bx!(VersionedAssets::V4(
+					Asset { id: native_asset.clone().into(), fun: treasury_balance.into() }.into()
+				)),
+				fee_asset_item: 0,
+			})),
+		});
+
+		// Dispatched from Root to `despatch_as` `Signed(treasury_account)`.
+		assert_ok!(teleport_call.dispatch(root));
+
+		assert_expected_events!(
+			Rococo,
+			vec![
+				RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {},
+			]
+		);
+	});
+
+	Rococo::execute_with(|| {
+		type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
+		type RuntimeCall = <Rococo as Chain>::RuntimeCall;
+		type RuntimeOrigin = <Rococo as Chain>::RuntimeOrigin;
+		type Runtime = <Rococo as Chain>::Runtime;
+		type Treasury = <Rococo as RococoPallet>::Treasury;
+
+		// Fund Alice account from Rococo Treasury account on Asset Hub.
+
+		let treasury_origin: RuntimeOrigin =
+			rococo_runtime::governance::pallet_custom_origins::Origin::Treasurer.into();
+
+		let alice_location: Location =
+			[Junction::AccountId32 { network: None, id: Rococo::account_id_of(ALICE).into() }]
+				.into();
+		let asset_hub_location: Location = [Parachain(1000)].into();
+		let native_asset = Location::parent();
+
+		let treasury_spend_call = RuntimeCall::Treasury(pallet_treasury::Call::<Runtime>::spend {
+			asset_kind: bx!(VersionedLocatableAsset::V4 {
+				location: asset_hub_location.clone(),
+				asset_id: native_asset.into(),
+			}),
+			amount: treasury_spend_balance,
+			beneficiary: bx!(VersionedLocation::V4(alice_location)),
+			valid_from: None,
+		});
+
+		assert_ok!(treasury_spend_call.dispatch(treasury_origin));
+
+		// Claim the spend.
+
+		let bob_signed = RuntimeOrigin::signed(Rococo::account_id_of(BOB));
+		assert_ok!(Treasury::payout(bob_signed.clone(), 0));
+
+		assert_expected_events!(
+			Rococo,
+			vec![
+				RuntimeEvent::Treasury(pallet_treasury::Event::AssetSpendApproved { .. }) => {},
+				RuntimeEvent::Treasury(pallet_treasury::Event::Paid { .. }) => {},
+			]
+		);
+	});
+
+	AssetHubRococo::execute_with(|| {
+		type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
+		type Balances = <AssetHubRococo as AssetHubRococoPallet>::Balances;
+
+		// Ensure that the funds deposited to Alice account.
+
+		let alice_account = AssetHubRococo::account_id_of(ALICE);
+		assert_eq!(
+			<Balances as Inspect<_>>::balance(&alice_account),
+			treasury_spend_balance + init_alice_balance
+		);
+
+		// Assert events triggered by xcm pay program:
+		// 1. treasury asset transferred to spend beneficiary;
+		// 2. response to Relay Chain Treasury pallet instance sent back;
+		// 3. XCM program completed;
+		assert_expected_events!(
+			AssetHubRococo,
+			vec![
+				RuntimeEvent::Balances(pallet_balances::Event::Transfer { .. }) => {},
+				RuntimeEvent::ParachainSystem(cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }) => {},
+				RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {},
+			]
+		);
+	});
+}
+
+#[test]
+fn create_and_claim_treasury_spend_in_usdt() {
+	const ASSET_ID: u32 = 1984;
+	const SPEND_AMOUNT: u128 = 1_000_000;
+	// treasury location from a sibling parachain.
+	let treasury_location: Location = Location::new(1, PalletInstance(18));
+	// treasury account on a sibling parachain.
+	let treasury_account =
+		asset_hub_rococo_runtime::xcm_config::LocationToAccountId::convert_location(
+			&treasury_location,
+		)
+		.unwrap();
+	let asset_hub_location =
+		v3::Location::new(0, v3::Junction::Parachain(AssetHubRococo::para_id().into()));
+	let root = <Rococo as Chain>::RuntimeOrigin::root();
+	// asset kind to be spend from the treasury.
+	let asset_kind = VersionedLocatableAsset::V3 {
+		location: asset_hub_location,
+		asset_id: v3::AssetId::Concrete(
+			(v3::Junction::PalletInstance(50), v3::Junction::GeneralIndex(ASSET_ID.into())).into(),
+		),
+	};
+	// treasury spend beneficiary.
+	let alice: AccountId = Rococo::account_id_of(ALICE);
+	let bob: AccountId = Rococo::account_id_of(BOB);
+	let bob_signed = <Rococo as Chain>::RuntimeOrigin::signed(bob.clone());
+
+	AssetHubRococo::execute_with(|| {
+		type Assets = <AssetHubRococo as AssetHubRococoPallet>::Assets;
+
+		// create an asset class and mint some assets to the treasury account.
+		assert_ok!(<Assets as Create<_>>::create(
+			ASSET_ID,
+			treasury_account.clone(),
+			true,
+			SPEND_AMOUNT / 2
+		));
+		assert_ok!(<Assets as Mutate<_>>::mint_into(ASSET_ID, &treasury_account, SPEND_AMOUNT * 4));
+		// beneficiary has zero balance.
+		assert_eq!(<Assets as FungiblesInspect<_>>::balance(ASSET_ID, &alice,), 0u128,);
+	});
+
+	Rococo::execute_with(|| {
+		type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
+		type Treasury = <Rococo as RococoPallet>::Treasury;
+		type AssetRate = <Rococo as RococoPallet>::AssetRate;
+
+		// create a conversion rate from `asset_kind` to the native currency.
+		assert_ok!(AssetRate::create(root.clone(), Box::new(asset_kind.clone()), 2.into()));
+
+		// create and approve a treasury spend.
+		assert_ok!(Treasury::spend(
+			root,
+			Box::new(asset_kind),
+			SPEND_AMOUNT,
+			Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()),
+			None,
+		));
+		// claim the spend.
+		assert_ok!(Treasury::payout(bob_signed.clone(), 0));
+
+		assert_expected_events!(
+			Rococo,
+			vec![
+				RuntimeEvent::Treasury(pallet_treasury::Event::Paid { .. }) => {},
+			]
+		);
+	});
+
+	AssetHubRococo::execute_with(|| {
+		type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
+		type Assets = <AssetHubRococo as AssetHubRococoPallet>::Assets;
+
+		// assert events triggered by xcm pay program
+		// 1. treasury asset transferred to spend beneficiary
+		// 2. response to Relay Chain treasury pallet instance sent back
+		// 3. XCM program completed
+		assert_expected_events!(
+			AssetHubRococo,
+			vec![
+				RuntimeEvent::Assets(pallet_assets::Event::Transferred { asset_id: id, from, to, amount }) => {
+					id: id == &ASSET_ID,
+					from: from == &treasury_account,
+					to: to == &alice,
+					amount: amount == &SPEND_AMOUNT,
+				},
+				RuntimeEvent::ParachainSystem(cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }) => {},
+				RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {},
+			]
+		);
+		// beneficiary received the assets from the treasury.
+		assert_eq!(<Assets as FungiblesInspect<_>>::balance(ASSET_ID, &alice,), SPEND_AMOUNT,);
+	});
+
+	Rococo::execute_with(|| {
+		type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
+		type Treasury = <Rococo as RococoPallet>::Treasury;
+
+		// check the payment status to ensure the response from the AssetHub was received.
+		assert_ok!(Treasury::check_status(bob_signed, 0));
+		assert_expected_events!(
+			Rococo,
+			vec![
+				RuntimeEvent::Treasury(pallet_treasury::Event::SpendProcessed { .. }) => {},
+			]
+		);
+	});
+}
diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..d1dbef9fc4156c08b2c52f54a3759de763c959e0
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/Cargo.toml
@@ -0,0 +1,43 @@
+[package]
+name = "collectives-westend-integration-tests"
+version = "1.0.0"
+authors.workspace = true
+edition.workspace = true
+license = "Apache-2.0"
+description = "Collectives Westend runtime integration tests with xcm-emulator"
+publish = false
+
+[lints]
+workspace = true
+
+[dependencies]
+codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
+assert_matches = "1.5.0"
+
+# Substrate
+sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false }
+frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false }
+pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false }
+pallet-asset-rate = { path = "../../../../../../../substrate/frame/asset-rate", default-features = false }
+pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false }
+pallet-treasury = { path = "../../../../../../../substrate/frame/treasury", default-features = false }
+pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue", default-features = false }
+pallet-utility = { path = "../../../../../../../substrate/frame/utility", default-features = false }
+
+# Polkadot
+polkadot-runtime-common = { path = "../../../../../../../polkadot/runtime/common" }
+xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false }
+xcm-executor = { package = "staging-xcm-executor", path = "../../../../../../../polkadot/xcm/xcm-executor", default-features = false }
+pallet-xcm = { path = "../../../../../../../polkadot/xcm/pallet-xcm", default-features = false }
+westend-runtime = { path = "../../../../../../../polkadot/runtime/westend" }
+westend-runtime-constants = { path = "../../../../../../../polkadot/runtime/westend/constants" }
+
+# Cumulus
+parachains-common = { path = "../../../../../../parachains/common" }
+testnet-parachains-constants = { path = "../../../../../runtimes/constants", features = ["westend"] }
+asset-hub-westend-runtime = { path = "../../../../../runtimes/assets/asset-hub-westend" }
+collectives-westend-runtime = { path = "../../../../../runtimes/collectives/collectives-westend" }
+cumulus-pallet-xcmp-queue = { default-features = false, path = "../../../../../../pallets/xcmp-queue" }
+cumulus-pallet-parachain-system = { default-features = false, path = "../../../../../../pallets/parachain-system" }
+emulated-integration-tests-common = { path = "../../../common", default-features = false }
+westend-system-emulated-network = { path = "../../../networks/westend-system" }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..97239330216ac8f66a7684811d1de30b13f56f7e
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs
@@ -0,0 +1,30 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+pub use xcm::{prelude::*, v3};
+
+pub use emulated_integration_tests_common::xcm_emulator::{
+	assert_expected_events, bx, Chain, RelayChain as Relay, TestExt,
+};
+pub use westend_system_emulated_network::{
+	asset_hub_westend_emulated_chain::AssetHubWestendParaPallet as AssetHubWestendPallet,
+	collectives_westend_emulated_chain::CollectivesWestendParaPallet as CollectivesWestendPallet,
+	westend_emulated_chain::WestendRelayPallet as WestendPallet,
+	AssetHubWestendPara as AssetHubWestend, CollectivesWestendPara as CollectivesWestend,
+	WestendRelay as Westend,
+};
+
+#[cfg(test)]
+mod tests;
diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs
new file mode 100644
index 0000000000000000000000000000000000000000..bde1220e2495bc544e507be1a8b40d77fcbde894
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs
@@ -0,0 +1,236 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::*;
+use asset_hub_westend_runtime::xcm_config::LocationToAccountId as AssetHubLocationToAccountId;
+use emulated_integration_tests_common::accounts::ALICE;
+use frame_support::{
+	assert_ok, dispatch::RawOrigin, instances::Instance1, sp_runtime::traits::Dispatchable,
+	traits::fungible::Inspect,
+};
+use polkadot_runtime_common::impls::VersionedLocatableAsset;
+use westend_runtime::OriginCaller;
+use westend_runtime_constants::currency::UNITS;
+use xcm_executor::traits::ConvertLocation;
+
+// Fund Fellowship Treasury from Westend Treasury and spend from Fellowship Treasury.
+#[test]
+fn fellowship_treasury_spend() {
+	// initial treasury balance on Asset Hub in WNDs.
+	let treasury_balance = 20_000_000 * UNITS;
+	// target fellowship balance on Asset Hub in WNDs.
+	let fellowship_treasury_balance = 1_000_000 * UNITS;
+	// fellowship first spend balance in WNDs.
+	let fellowship_spend_balance = 10_000 * UNITS;
+
+	let init_alice_balance = AssetHubWestend::execute_with(|| {
+		<<AssetHubWestend as AssetHubWestendPallet>::Balances as Inspect<_>>::balance(
+			&AssetHubWestend::account_id_of(ALICE),
+		)
+	});
+
+	Westend::execute_with(|| {
+		type RuntimeEvent = <Westend as Chain>::RuntimeEvent;
+		type RuntimeCall = <Westend as Chain>::RuntimeCall;
+		type Runtime = <Westend as Chain>::Runtime;
+		type Balances = <Westend as WestendPallet>::Balances;
+		type Treasury = <Westend as WestendPallet>::Treasury;
+
+		// Fund Treasury account on Asset Hub with WNDs.
+
+		let root = <Westend as Chain>::RuntimeOrigin::root();
+		let treasury_account = Treasury::account_id();
+
+		// Mist assets to Treasury account on Relay Chain.
+		assert_ok!(Balances::force_set_balance(
+			root.clone(),
+			treasury_account.clone().into(),
+			treasury_balance * 2,
+		));
+
+		let native_asset = Location::here();
+		let asset_hub_location: Location = [Parachain(1000)].into();
+		let treasury_location: Location = (Parent, PalletInstance(37)).into();
+
+		let teleport_call = RuntimeCall::Utility(pallet_utility::Call::<Runtime>::dispatch_as {
+			as_origin: bx!(OriginCaller::system(RawOrigin::Signed(treasury_account))),
+			call: bx!(RuntimeCall::XcmPallet(pallet_xcm::Call::<Runtime>::teleport_assets {
+				dest: bx!(VersionedLocation::V4(asset_hub_location.clone())),
+				beneficiary: bx!(VersionedLocation::V4(treasury_location)),
+				assets: bx!(VersionedAssets::V4(
+					Asset { id: native_asset.clone().into(), fun: treasury_balance.into() }.into()
+				)),
+				fee_asset_item: 0,
+			})),
+		});
+
+		// Dispatched from Root to `dispatch_as` `Signed(treasury_account)`.
+		assert_ok!(teleport_call.dispatch(root));
+
+		assert_expected_events!(
+			Westend,
+			vec![
+				RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {},
+			]
+		);
+	});
+
+	Westend::execute_with(|| {
+		type RuntimeEvent = <Westend as Chain>::RuntimeEvent;
+		type RuntimeCall = <Westend as Chain>::RuntimeCall;
+		type RuntimeOrigin = <Westend as Chain>::RuntimeOrigin;
+		type Runtime = <Westend as Chain>::Runtime;
+		type Treasury = <Westend as WestendPallet>::Treasury;
+
+		// Fund Fellowship Treasury from Westend Treasury.
+
+		let treasury_origin: RuntimeOrigin =
+			westend_runtime::governance::pallet_custom_origins::Origin::Treasurer.into();
+		let fellowship_treasury_location: Location =
+			Location::new(1, [Parachain(1001), PalletInstance(65)]);
+		let asset_hub_location: Location = [Parachain(1000)].into();
+		let native_asset = Location::parent();
+
+		let treasury_spend_call = RuntimeCall::Treasury(pallet_treasury::Call::<Runtime>::spend {
+			asset_kind: bx!(VersionedLocatableAsset::V4 {
+				location: asset_hub_location.clone(),
+				asset_id: native_asset.into(),
+			}),
+			amount: fellowship_treasury_balance,
+			beneficiary: bx!(VersionedLocation::V4(fellowship_treasury_location)),
+			valid_from: None,
+		});
+
+		assert_ok!(treasury_spend_call.dispatch(treasury_origin));
+
+		// Claim the spend.
+
+		let alice_signed = RuntimeOrigin::signed(Westend::account_id_of(ALICE));
+		assert_ok!(Treasury::payout(alice_signed.clone(), 0));
+
+		assert_expected_events!(
+			Westend,
+			vec![
+				RuntimeEvent::Treasury(pallet_treasury::Event::AssetSpendApproved { .. }) => {},
+				RuntimeEvent::Treasury(pallet_treasury::Event::Paid { .. }) => {},
+			]
+		);
+	});
+
+	AssetHubWestend::execute_with(|| {
+		type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
+		type Balances = <AssetHubWestend as AssetHubWestendPallet>::Balances;
+
+		// Ensure that the funds deposited to the Fellowship Treasury account.
+
+		let fellowship_treasury_location: Location =
+			Location::new(1, [Parachain(1001), PalletInstance(65)]);
+		let fellowship_treasury_account =
+			AssetHubLocationToAccountId::convert_location(&fellowship_treasury_location).unwrap();
+
+		assert_eq!(
+			<Balances as Inspect<_>>::balance(&fellowship_treasury_account),
+			fellowship_treasury_balance
+		);
+
+		// Assert events triggered by xcm pay program:
+		// 1. treasury asset transferred to spend beneficiary;
+		// 2. response to Relay Chain Treasury pallet instance sent back;
+		// 3. XCM program completed;
+		assert_expected_events!(
+			AssetHubWestend,
+			vec![
+				RuntimeEvent::Balances(pallet_balances::Event::Transfer { .. }) => {},
+				RuntimeEvent::ParachainSystem(cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }) => {},
+				RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {},
+			]
+		);
+	});
+
+	CollectivesWestend::execute_with(|| {
+		type RuntimeEvent = <CollectivesWestend as Chain>::RuntimeEvent;
+		type RuntimeCall = <CollectivesWestend as Chain>::RuntimeCall;
+		type RuntimeOrigin = <CollectivesWestend as Chain>::RuntimeOrigin;
+		type Runtime = <CollectivesWestend as Chain>::Runtime;
+		type FellowshipTreasury =
+			<CollectivesWestend as CollectivesWestendPallet>::FellowshipTreasury;
+
+		// Fund Alice account from Fellowship Treasury.
+
+		let fellows_origin: RuntimeOrigin =
+			collectives_westend_runtime::fellowship::pallet_fellowship_origins::Origin::Fellows
+				.into();
+		let asset_hub_location: Location = (Parent, Parachain(1000)).into();
+		let native_asset = Location::parent();
+
+		let alice_location: Location = [Junction::AccountId32 {
+			network: None,
+			id: CollectivesWestend::account_id_of(ALICE).into(),
+		}]
+		.into();
+
+		let fellowship_treasury_spend_call =
+			RuntimeCall::FellowshipTreasury(pallet_treasury::Call::<Runtime, Instance1>::spend {
+				asset_kind: bx!(VersionedLocatableAsset::V4 {
+					location: asset_hub_location,
+					asset_id: native_asset.into(),
+				}),
+				amount: fellowship_spend_balance,
+				beneficiary: bx!(VersionedLocation::V4(alice_location)),
+				valid_from: None,
+			});
+
+		assert_ok!(fellowship_treasury_spend_call.dispatch(fellows_origin));
+
+		// Claim the spend.
+
+		let alice_signed = RuntimeOrigin::signed(CollectivesWestend::account_id_of(ALICE));
+		assert_ok!(FellowshipTreasury::payout(alice_signed.clone(), 0));
+
+		assert_expected_events!(
+			CollectivesWestend,
+			vec![
+				RuntimeEvent::FellowshipTreasury(pallet_treasury::Event::AssetSpendApproved { .. }) => {},
+				RuntimeEvent::FellowshipTreasury(pallet_treasury::Event::Paid { .. }) => {},
+			]
+		);
+	});
+
+	AssetHubWestend::execute_with(|| {
+		type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
+		type Balances = <AssetHubWestend as AssetHubWestendPallet>::Balances;
+
+		// Ensure that the funds deposited to Alice account.
+
+		let alice_account = AssetHubWestend::account_id_of(ALICE);
+		assert_eq!(
+			<Balances as Inspect<_>>::balance(&alice_account),
+			fellowship_spend_balance + init_alice_balance
+		);
+
+		// Assert events triggered by xcm pay program:
+		// 1. treasury asset transferred to spend beneficiary;
+		// 2. response to Relay Chain Treasury pallet instance sent back;
+		// 3. XCM program completed;
+		assert_expected_events!(
+			AssetHubWestend,
+			vec![
+				RuntimeEvent::Balances(pallet_balances::Event::Transfer { .. }) => {},
+				RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
+				RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {},
+			]
+		);
+	});
+}
diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a9f65df34b647835b4ce5585be6b53b0489de578
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs
@@ -0,0 +1,16 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+mod fellowship_treasury;
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs
index 3816d2ed848ed51740283ffea31e9f7e53c01f1a..94765287637b57d47c588d9a4359666d1b54f509 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs
@@ -21,13 +21,16 @@ mod tracks;
 use crate::{
 	weights,
 	xcm_config::{FellowshipAdminBodyId, LocationToAccountId, TreasurerBodyId, UsdtAssetHub},
-	AccountId, AssetRate, Balance, Balances, FellowshipReferenda, GovernanceLocation, Preimage,
-	Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, WestendTreasuryAccount, DAYS,
+	AccountId, AssetRate, Balance, Balances, FellowshipReferenda, GovernanceLocation,
+	ParachainInfo, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler,
+	WestendTreasuryAccount, DAYS,
 };
+use cumulus_primitives_core::ParaId;
 use frame_support::{
 	parameter_types,
 	traits::{
-		EitherOf, EitherOfDiverse, MapSuccess, NeverEnsureOrigin, OriginTrait, TryWithMorphedArg,
+		tokens::UnityOrOuterConversion, EitherOf, EitherOfDiverse, FromContains, MapSuccess,
+		NeverEnsureOrigin, OriginTrait, TryWithMorphedArg,
 	},
 	PalletId,
 };
@@ -40,10 +43,10 @@ use pallet_ranked_collective::EnsureOfRank;
 use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
 use parachains_common::impls::ToParentTreasury;
 use polkadot_runtime_common::impls::{
-	LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter,
+	ContainsParts, LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter,
 };
 use sp_arithmetic::Permill;
-use sp_core::{ConstU128, ConstU32};
+use sp_core::{ConstU128, ConstU32, ConstU8};
 use sp_runtime::traits::{ConstU16, ConvertToValue, IdentityLookup, Replace, TakeFirst};
 use testnet_parachains_constants::westend::{account, currency::GRAND};
 use westend_runtime_constants::time::HOURS;
@@ -263,6 +266,7 @@ parameter_types! {
 	// The asset's interior location for the paying account. This is the Fellowship Treasury
 	// pallet instance (which sits at index 65).
 	pub FellowshipTreasuryInteriorLocation: InteriorLocation = PalletInstance(65).into();
+	pub SelfParaId: ParaId = ParachainInfo::parachain_id();
 }
 
 #[cfg(feature = "runtime-benchmarks")]
@@ -345,7 +349,15 @@ impl pallet_treasury::Config<FellowshipTreasuryInstance> for Runtime {
 	type Paymaster = FellowshipTreasuryPaymaster;
 	#[cfg(feature = "runtime-benchmarks")]
 	type Paymaster = PayWithEnsure<FellowshipTreasuryPaymaster, OpenHrmpChannel<ConstU32<1000>>>;
-	type BalanceConverter = AssetRate;
+	type BalanceConverter = UnityOrOuterConversion<
+		ContainsParts<
+			FromContains<
+				xcm_builder::IsSiblingSystemParachain<ParaId, SelfParaId>,
+				xcm_builder::IsParentsOnly<ConstU8<1>>,
+			>,
+		>,
+		AssetRate,
+	>;
 	type PayoutPeriod = ConstU32<{ 30 * DAYS }>;
 	#[cfg(feature = "runtime-benchmarks")]
 	type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments<
diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs
index cc1243790c2e58b23c169de918f28d75397420ba..85531e9c04fc47f83fb007802e30e87799c2150c 100644
--- a/polkadot/runtime/common/src/impls.rs
+++ b/polkadot/runtime/common/src/impls.rs
@@ -19,7 +19,7 @@
 use frame_support::traits::{
 	fungible::{Balanced, Credit},
 	tokens::imbalance::ResolveTo,
-	Imbalance, OnUnbalanced,
+	Contains, ContainsPair, Imbalance, OnUnbalanced,
 };
 use pallet_treasury::TreasuryAccountId;
 use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
@@ -156,6 +156,26 @@ impl TryConvert<&VersionedLocation, xcm::latest::Location> for VersionedLocation
 	}
 }
 
+/// Adapter for [`Contains`] trait to match [`VersionedLocatableAsset`] type converted to the latest
+/// version of itself where it's location matched by `L` and it's asset id by `A` parameter types.
+pub struct ContainsParts<C>(core::marker::PhantomData<C>);
+impl<C> Contains<VersionedLocatableAsset> for ContainsParts<C>
+where
+	C: ContainsPair<xcm::latest::Location, xcm::latest::Location>,
+{
+	fn contains(asset: &VersionedLocatableAsset) -> bool {
+		use VersionedLocatableAsset::*;
+		let (location, asset_id) = match asset.clone() {
+			V3 { location, asset_id } => match (location.try_into(), asset_id.try_into()) {
+				(Ok(l), Ok(a)) => (l, a),
+				_ => return false,
+			},
+			V4 { location, asset_id } => (location, asset_id),
+		};
+		C::contains(&location, &asset_id.0)
+	}
+}
+
 #[cfg(feature = "runtime-benchmarks")]
 pub mod benchmarks {
 	use super::VersionedLocatableAsset;
diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs
index 740a6240d39526cec795ba082848a480c8a7e3a3..ba80fa6942c7791e9166281f0bdf2199a41cf10f 100644
--- a/polkadot/runtime/rococo/src/lib.rs
+++ b/polkadot/runtime/rococo/src/lib.rs
@@ -25,7 +25,10 @@ use beefy_primitives::{
 	ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature},
 	mmr::{BeefyDataProvider, MmrLeafVersion},
 };
-use frame_support::dynamic_params::{dynamic_pallet_params, dynamic_params};
+use frame_support::{
+	dynamic_params::{dynamic_pallet_params, dynamic_params},
+	traits::FromContains,
+};
 use pallet_nis::WithMaximumOf;
 use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
 use primitives::{
@@ -40,7 +43,8 @@ use rococo_runtime_constants::system_parachain::BROKER_ID;
 use runtime_common::{
 	assigned_slots, auctions, claims, crowdloan, identity_migrator, impl_runtime_weights,
 	impls::{
-		LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter,
+		ContainsParts, LocatableAssetConverter, ToAuthor, VersionedLocatableAsset,
+		VersionedLocationConverter,
 	},
 	paras_registrar, paras_sudo_wrapper, prod_or_fast, slots,
 	traits::{Leaser, OnSwap},
@@ -74,10 +78,10 @@ use frame_support::{
 	genesis_builder_helper::{build_state, get_preset},
 	parameter_types,
 	traits::{
-		fungible::HoldConsideration, Contains, EitherOf, EitherOfDiverse, EnsureOrigin,
-		EnsureOriginWithArg, EverythingBut, InstanceFilter, KeyOwnerProofSystem,
-		LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, StorageMapShim,
-		WithdrawReasons,
+		fungible::HoldConsideration, tokens::UnityOrOuterConversion, Contains, EitherOf,
+		EitherOfDiverse, EnsureOrigin, EnsureOriginWithArg, EverythingBut, InstanceFilter,
+		KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError,
+		StorageMapShim, WithdrawReasons,
 	},
 	weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
 	PalletId,
@@ -87,7 +91,7 @@ use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
 use pallet_identity::legacy::IdentityInfo;
 use pallet_session::historical as session_historical;
 use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo};
-use sp_core::{ConstU128, OpaqueMetadata, H256};
+use sp_core::{ConstU128, ConstU8, OpaqueMetadata, H256};
 use sp_runtime::{
 	create_runtime_str, generic, impl_opaque_keys,
 	traits::{
@@ -523,7 +527,15 @@ impl pallet_treasury::Config for Runtime {
 		LocatableAssetConverter,
 		VersionedLocationConverter,
 	>;
-	type BalanceConverter = AssetRate;
+	type BalanceConverter = UnityOrOuterConversion<
+		ContainsParts<
+			FromContains<
+				xcm_builder::IsChildSystemParachain<ParaId>,
+				xcm_builder::IsParentsOnly<ConstU8<1>>,
+			>,
+		>,
+		AssetRate,
+	>;
 	type PayoutPeriod = PayoutSpendPeriod;
 	#[cfg(feature = "runtime-benchmarks")]
 	type BenchmarkHelper = runtime_common::impls::benchmarks::TreasuryArguments;
diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs
index a119d78b83ab8a76642d0bc1cf407ec4935ab5dc..a06a1e1f7fc8dfbefee8aae69194265b80fbd8c5 100644
--- a/polkadot/runtime/westend/src/lib.rs
+++ b/polkadot/runtime/westend/src/lib.rs
@@ -31,9 +31,9 @@ use frame_support::{
 	genesis_builder_helper::{build_state, get_preset},
 	parameter_types,
 	traits::{
-		fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut,
-		InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage,
-		ProcessMessageError, WithdrawReasons,
+		fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf,
+		EitherOfDiverse, EverythingBut, FromContains, InstanceFilter, KeyOwnerProofSystem,
+		LinearStoragePrice, ProcessMessage, ProcessMessageError, WithdrawReasons,
 	},
 	weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
 	PalletId,
@@ -57,7 +57,8 @@ use runtime_common::{
 	elections::OnChainAccuracy,
 	identity_migrator, impl_runtime_weights,
 	impls::{
-		LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter,
+		ContainsParts, LocatableAssetConverter, ToAuthor, VersionedLocatableAsset,
+		VersionedLocationConverter,
 	},
 	paras_registrar, paras_sudo_wrapper, prod_or_fast, slots,
 	traits::{Leaser, OnSwap},
@@ -80,7 +81,7 @@ use runtime_parachains::{
 	shared as parachains_shared,
 };
 use scale_info::TypeInfo;
-use sp_core::{OpaqueMetadata, RuntimeDebug, H256};
+use sp_core::{ConstU8, OpaqueMetadata, RuntimeDebug, H256};
 use sp_runtime::{
 	create_runtime_str,
 	curve::PiecewiseLinear,
@@ -712,7 +713,15 @@ impl pallet_treasury::Config for Runtime {
 		LocatableAssetConverter,
 		VersionedLocationConverter,
 	>;
-	type BalanceConverter = AssetRate;
+	type BalanceConverter = UnityOrOuterConversion<
+		ContainsParts<
+			FromContains<
+				xcm_builder::IsChildSystemParachain<ParaId>,
+				xcm_builder::IsParentsOnly<ConstU8<1>>,
+			>,
+		>,
+		AssetRate,
+	>;
 	type PayoutPeriod = PayoutSpendPeriod;
 	#[cfg(feature = "runtime-benchmarks")]
 	type BenchmarkHelper = runtime_common::impls::benchmarks::TreasuryArguments;
diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs
index b8923a4d5c6e88d9034536fa4dacf21c47e9108b..c0b328f38e96b23dbadcda4dd8fc1aacf9620d5d 100644
--- a/polkadot/xcm/xcm-builder/src/barriers.rs
+++ b/polkadot/xcm/xcm-builder/src/barriers.rs
@@ -322,6 +322,29 @@ impl<ParaId: IsSystem + From<u32>> Contains<Location> for IsChildSystemParachain
 	}
 }
 
+/// Matches if the given location is a system-level sibling parachain.
+pub struct IsSiblingSystemParachain<ParaId, SelfParaId>(PhantomData<(ParaId, SelfParaId)>);
+impl<ParaId: IsSystem + From<u32> + Eq, SelfParaId: Get<ParaId>> Contains<Location>
+	for IsSiblingSystemParachain<ParaId, SelfParaId>
+{
+	fn contains(l: &Location) -> bool {
+		matches!(
+			l.unpack(),
+			(1, [Junction::Parachain(id)])
+				if SelfParaId::get() != ParaId::from(*id) && ParaId::from(*id).is_system(),
+		)
+	}
+}
+
+/// Matches if the given location contains only the specified amount of parents and no interior
+/// junctions.
+pub struct IsParentsOnly<Count>(PhantomData<Count>);
+impl<Count: Get<u8>> Contains<Location> for IsParentsOnly<Count> {
+	fn contains(t: &Location) -> bool {
+		t.contains_parents_only(Count::get())
+	}
+}
+
 /// Allows only messages if the generic `ResponseHandler` expects them via `expecting_response`.
 pub struct AllowKnownQueryResponses<ResponseHandler>(PhantomData<ResponseHandler>);
 impl<ResponseHandler: OnResponse> ShouldExecute for AllowKnownQueryResponses<ResponseHandler> {
diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs
index c3400cc72b48e97cb2cdfd85a028b21b7c032963..bd4a4c941c915c8da1f9c05d35444d86ac7668e8 100644
--- a/polkadot/xcm/xcm-builder/src/lib.rs
+++ b/polkadot/xcm/xcm-builder/src/lib.rs
@@ -37,8 +37,8 @@ mod barriers;
 pub use barriers::{
 	AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom,
 	AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, DenyReserveTransferToRelayChain,
-	DenyThenTry, IsChildSystemParachain, RespectSuspension, TakeWeightCredit, TrailingSetTopicAsId,
-	WithComputedOrigin,
+	DenyThenTry, IsChildSystemParachain, IsParentsOnly, IsSiblingSystemParachain,
+	RespectSuspension, TakeWeightCredit, TrailingSetTopicAsId, WithComputedOrigin,
 };
 
 mod controller;
diff --git a/prdoc/pr_3659.prdoc b/prdoc/pr_3659.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..393844d822d864bca595a0257f02989fb4a19ac7
--- /dev/null
+++ b/prdoc/pr_3659.prdoc
@@ -0,0 +1,12 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Unity Balance Conversion for Different IDs of Native Asset 
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      Introduce types to define 1:1 balance conversion for different relative asset ids/locations 
+      of native asset for `ConversionToAssetBalance` trait bounds.
+
+crates: [ ]
\ No newline at end of file
diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs
index 66777cef7b8e81960c1169c2fb1fd1033e58c4a2..a423656c394f28158da2aedd5d552814ccabb3c5 100644
--- a/substrate/frame/support/src/traits.rs
+++ b/substrate/frame/support/src/traits.rs
@@ -36,7 +36,7 @@ mod members;
 pub use members::{AllowAll, DenyAll, Filter};
 pub use members::{
 	AsContains, ChangeMembers, Contains, ContainsLengthBound, ContainsPair, Equals, Everything,
-	EverythingBut, FromContainsPair, InitializeMembers, InsideBoth, IsInVec, Nothing,
+	EverythingBut, FromContains, FromContainsPair, InitializeMembers, InsideBoth, IsInVec, Nothing,
 	RankedMembers, RankedMembersSwapHandler, SortedMembers, TheseExcept,
 };
 
diff --git a/substrate/frame/support/src/traits/members.rs b/substrate/frame/support/src/traits/members.rs
index 3a6e3719593a22c33ad24c24c56f858ea82779ee..53de84ab22455f2d778c1fd64ba94c348c685db0 100644
--- a/substrate/frame/support/src/traits/members.rs
+++ b/substrate/frame/support/src/traits/members.rs
@@ -66,6 +66,15 @@ impl<A, B, CP: ContainsPair<A, B>> Contains<(A, B)> for FromContainsPair<CP> {
 	}
 }
 
+/// A [`ContainsPair`] implementation that has a `Contains` implementation for each member of the
+/// pair.
+pub struct FromContains<CA, CB>(PhantomData<(CA, CB)>);
+impl<A, B, CA: Contains<A>, CB: Contains<B>> ContainsPair<A, B> for FromContains<CA, CB> {
+	fn contains(a: &A, b: &B) -> bool {
+		CA::contains(a) && CB::contains(b)
+	}
+}
+
 /// A [`Contains`] implementation that contains every value.
 pub enum Everything {}
 impl<T> Contains<T> for Everything {
diff --git a/substrate/frame/support/src/traits/tokens.rs b/substrate/frame/support/src/traits/tokens.rs
index 3635311e64357bbd2e7041d653a4268dfb65a182..8842b20580181f81e4377a0d9f6223e59a6fee6a 100644
--- a/substrate/frame/support/src/traits/tokens.rs
+++ b/substrate/frame/support/src/traits/tokens.rs
@@ -31,7 +31,7 @@ pub mod pay;
 pub use misc::{
 	AssetId, Balance, BalanceStatus, ConversionFromAssetBalance, ConversionToAssetBalance,
 	ConvertRank, DepositConsequence, ExistenceRequirement, Fortitude, GetSalary, Locker, Precision,
-	Preservation, Provenance, Restriction, UnityAssetBalanceConversion, WithdrawConsequence,
-	WithdrawReasons,
+	Preservation, Provenance, Restriction, UnityAssetBalanceConversion, UnityOrOuterConversion,
+	WithdrawConsequence, WithdrawReasons,
 };
 pub use pay::{Pay, PayFromAccount, PaymentStatus};
diff --git a/substrate/frame/support/src/traits/tokens/misc.rs b/substrate/frame/support/src/traits/tokens/misc.rs
index a4dd5e4914283e6da028aac038cecee501a2228f..424acb1d550b15b69582d004e2e466e65e6a9b3f 100644
--- a/substrate/frame/support/src/traits/tokens/misc.rs
+++ b/substrate/frame/support/src/traits/tokens/misc.rs
@@ -17,6 +17,7 @@
 
 //! Miscellaneous types.
 
+use crate::traits::Contains;
 use codec::{Decode, Encode, FullCodec, MaxEncodedLen};
 use sp_arithmetic::traits::{AtLeast32BitUnsigned, Zero};
 use sp_core::RuntimeDebug;
@@ -299,6 +300,33 @@ where
 	fn ensure_successful(_: AssetId) {}
 }
 
+/// Implements [`ConversionFromAssetBalance`], allowing for a 1:1 balance conversion of the asset
+/// when it meets the conditions specified by `C`. If the conditions are not met, the conversion is
+/// delegated to `O`.
+pub struct UnityOrOuterConversion<C, O>(core::marker::PhantomData<(C, O)>);
+impl<AssetBalance, AssetId, OutBalance, C, O>
+	ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> for UnityOrOuterConversion<C, O>
+where
+	C: Contains<AssetId>,
+	O: ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance>,
+	AssetBalance: Into<OutBalance>,
+{
+	type Error = O::Error;
+	fn from_asset_balance(
+		balance: AssetBalance,
+		asset_id: AssetId,
+	) -> Result<OutBalance, Self::Error> {
+		if C::contains(&asset_id) {
+			return Ok(balance.into());
+		}
+		O::from_asset_balance(balance, asset_id)
+	}
+	#[cfg(feature = "runtime-benchmarks")]
+	fn ensure_successful(asset_id: AssetId) {
+		O::ensure_successful(asset_id)
+	}
+}
+
 /// Trait to handle NFT locking mechanism to ensure interactions with the asset can be implemented
 /// downstream to extend logic of Uniques/Nfts current functionality.
 pub trait Locker<CollectionId, ItemId> {