diff --git a/Cargo.lock b/Cargo.lock
index 40594efe42d3a509e035238ea8bd89e3e42262eb..6ad92da6958d08a18206b3d2b3e8287f36c469c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2868,6 +2868,7 @@ version = "1.0.0"
 dependencies = [
  "asset-hub-westend-runtime",
  "bridge-hub-westend-runtime",
+ "cumulus-pallet-parachain-system 0.7.0",
  "cumulus-pallet-xcmp-queue 0.7.0",
  "emulated-integration-tests-common",
  "frame-support 28.0.0",
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml
index f718e7e77f597723c2a53dac3552bb103bab96d9..05c7021d380aeb0eaec892dd00cecc102c836f02 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml
@@ -37,6 +37,7 @@ pallet-bridge-messages = { workspace = true }
 # Cumulus
 asset-hub-westend-runtime = { workspace = true }
 bridge-hub-westend-runtime = { workspace = true }
+cumulus-pallet-parachain-system = { workspace = true }
 cumulus-pallet-xcmp-queue = { workspace = true }
 emulated-integration-tests-common = { workspace = true }
 parachains-common = { workspace = true, default-features = true }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs
index 3d4d4f58e3b54f2baf8fc9dcf5683e9b3be4532f..cd5e22372f0e645469cdee8c8fb47ab901456ea4 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs
@@ -61,8 +61,10 @@ mod imports {
 				LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub,
 				UniversalLocation as PenpalUniversalLocation,
 			},
-			PenpalAssetOwner, PenpalBParaPallet as PenpalBPallet,
+			PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner,
+			PenpalBParaPallet as PenpalBPallet,
 		},
+		rococo_emulated_chain::RococoRelayPallet as RococoPallet,
 		westend_emulated_chain::{
 			genesis::ED as WESTEND_ED, westend_runtime::xcm_config::XcmConfig as WestendXcmConfig,
 			WestendRelayPallet as WestendPallet,
@@ -73,10 +75,11 @@ mod imports {
 		AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo,
 		BridgeHubWestendPara as BridgeHubWestend,
 		BridgeHubWestendParaReceiver as BridgeHubWestendReceiver,
-		BridgeHubWestendParaSender as BridgeHubWestendSender, PenpalBPara as PenpalB,
+		BridgeHubWestendParaSender as BridgeHubWestendSender, PenpalAPara as PenpalA,
+		PenpalAParaReceiver as PenpalAReceiver, PenpalBPara as PenpalB,
 		PenpalBParaReceiver as PenpalBReceiver, PenpalBParaSender as PenpalBSender,
-		WestendRelay as Westend, WestendRelayReceiver as WestendReceiver,
-		WestendRelaySender as WestendSender,
+		RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, WestendRelay as Westend,
+		WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender,
 	};
 
 	pub const ASSET_ID: u32 = 1;
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs
index a73c1280b406a7154c05707a4dfe53946ac9c1c9..6da4de550fb5f5dcf5b949ccd5297fd4e2897f01 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs
@@ -14,6 +14,7 @@
 // limitations under the License.
 
 use crate::{create_pool_with_native_on, tests::*};
+use emulated_integration_tests_common::macros::Dmp;
 use xcm::latest::AssetTransferFilter;
 
 fn send_assets_over_bridge<F: FnOnce()>(send_fn: F) {
@@ -41,6 +42,12 @@ fn set_up_wnds_for_penpal_westend_through_ahw_to_ahr(
 	let wnd_at_westend_parachains = wnd_at_ah_westend();
 	let wnd_at_asset_hub_rococo = bridged_wnd_at_ah_rococo();
 	create_foreign_on_ah_rococo(wnd_at_asset_hub_rococo.clone(), true);
+	create_pool_with_native_on!(
+		AssetHubRococo,
+		wnd_at_asset_hub_rococo.clone(),
+		true,
+		AssetHubRococoSender::get()
+	);
 
 	let penpal_location = AssetHubWestend::sibling_location_of(PenpalB::para_id());
 	let sov_penpal_on_ahw = AssetHubWestend::sovereign_account_id_of(penpal_location);
@@ -416,6 +423,295 @@ fn send_wnds_from_penpal_westend_through_asset_hub_westend_to_asset_hub_rococo()
 	assert!(wnds_in_reserve_on_ahw_after <= wnds_in_reserve_on_ahw_before + amount);
 }
 
+#[test]
+fn send_wnds_from_penpal_westend_through_asset_hub_westend_to_asset_hub_rococo_to_penpal_rococo() {
+	let amount = ASSET_HUB_WESTEND_ED * 10_000_000;
+	let sender = PenpalBSender::get();
+	let receiver = PenpalAReceiver::get();
+	let local_asset_hub = PenpalB::sibling_location_of(AssetHubWestend::para_id());
+	// create foreign WND on remote paras
+	let (wnd_at_westend_parachains, wnd_at_rococo_parachains) =
+		set_up_wnds_for_penpal_westend_through_ahw_to_ahr(&sender, amount);
+	let asset_owner: AccountId = AssetHubRococo::account_id_of(ALICE);
+	// create foreign WND on remote paras
+	PenpalA::force_create_foreign_asset(
+		wnd_at_rococo_parachains.clone(),
+		asset_owner.clone(),
+		true,
+		ASSET_MIN_BALANCE,
+		vec![],
+	);
+	// Configure destination Penpal chain to trust its sibling AH as reserve of bridged WND
+	PenpalA::execute_with(|| {
+		assert_ok!(<PenpalA as Chain>::System::set_storage(
+			<PenpalA as Chain>::RuntimeOrigin::root(),
+			vec![(
+				PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
+				wnd_at_rococo_parachains.encode(),
+			)],
+		));
+	});
+	create_pool_with_native_on!(PenpalA, wnd_at_rococo_parachains.clone(), true, asset_owner);
+
+	let sov_ahr_on_ahw = AssetHubWestend::sovereign_account_of_parachain_on_other_global_consensus(
+		ByGenesis(ROCOCO_GENESIS_HASH),
+		AssetHubRococo::para_id(),
+	);
+	let wnds_in_reserve_on_ahw_before =
+		<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
+	let sender_wnds_before = PenpalB::execute_with(|| {
+		type ForeignAssets = <PenpalB as PenpalBPallet>::ForeignAssets;
+		<ForeignAssets as Inspect<_>>::balance(wnd_at_westend_parachains.clone(), &sender)
+	});
+	let receiver_wnds_before = PenpalA::execute_with(|| {
+		type Assets = <PenpalA as PenpalAPallet>::ForeignAssets;
+		<Assets as Inspect<_>>::balance(wnd_at_rococo_parachains.clone(), &receiver)
+	});
+
+	// Send WNDs over bridge
+	{
+		let destination = asset_hub_rococo_location();
+		let assets: Assets = (wnd_at_westend_parachains.clone(), amount).into();
+		let asset_transfer_type = TransferType::RemoteReserve(local_asset_hub.clone().into());
+		let fees_id: AssetId = wnd_at_westend_parachains.clone().into();
+		let fees_transfer_type = TransferType::RemoteReserve(local_asset_hub.into());
+		let remote_fees = (bridged_wnd_at_ah_rococo(), amount / 2).into();
+		let beneficiary: Location =
+			AccountId32Junction { network: None, id: receiver.clone().into() }.into();
+		let custom_xcm_on_penpal_dest = Xcm::<()>(vec![
+			BuyExecution { fees: remote_fees, weight_limit: Unlimited },
+			DepositAsset { assets: Wild(AllCounted(assets.len() as u32)), beneficiary },
+		]);
+		let pp_loc_from_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id());
+		let custom_xcm_on_remote_ah = Xcm::<()>(vec![
+			// BuyExecution { fees: remote_fees, weight_limit: Unlimited },
+			DepositReserveAsset {
+				assets: Wild(AllCounted(1)),
+				dest: pp_loc_from_ah,
+				xcm: custom_xcm_on_penpal_dest,
+			},
+		]);
+		send_assets_from_penpal_westend_through_westend_ah_to_rococo_ah(
+			destination,
+			(assets, asset_transfer_type),
+			(fees_id, fees_transfer_type),
+			custom_xcm_on_remote_ah,
+		);
+	}
+
+	// process AHR incoming message and check events
+	AssetHubRococo::execute_with(|| {
+		type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			AssetHubRococo,
+			vec![
+				// issue WNDs on AHR
+				RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
+				// message processed successfully
+				RuntimeEvent::MessageQueue(
+					pallet_message_queue::Event::Processed { success: true, .. }
+				) => {},
+			]
+		);
+	});
+	PenpalA::execute_with(|| {
+		PenpalA::assert_xcmp_queue_success(None);
+	});
+
+	let sender_wnds_after = PenpalB::execute_with(|| {
+		type ForeignAssets = <PenpalB as PenpalBPallet>::ForeignAssets;
+		<ForeignAssets as Inspect<_>>::balance(wnd_at_westend_parachains, &sender)
+	});
+	let receiver_wnds_after = PenpalA::execute_with(|| {
+		type Assets = <PenpalA as PenpalAPallet>::ForeignAssets;
+		<Assets as Inspect<_>>::balance(wnd_at_rococo_parachains, &receiver)
+	});
+	let wnds_in_reserve_on_ahw_after =
+		<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
+
+	// Sender's balance is reduced
+	assert!(sender_wnds_after < sender_wnds_before);
+	// Receiver's balance is increased
+	assert!(receiver_wnds_after > receiver_wnds_before);
+	// Reserve balance is increased by sent amount (less fess)
+	assert!(wnds_in_reserve_on_ahw_after > wnds_in_reserve_on_ahw_before);
+	assert!(wnds_in_reserve_on_ahw_after <= wnds_in_reserve_on_ahw_before + amount);
+}
+
+#[test]
+fn send_wnds_from_westend_relay_through_asset_hub_westend_to_asset_hub_rococo_to_penpal_rococo() {
+	let amount = WESTEND_ED * 1_000;
+	let sender = WestendSender::get();
+	let receiver = PenpalAReceiver::get();
+	let local_asset_hub = Westend::child_location_of(AssetHubWestend::para_id());
+
+	let wnd_at_westend_parachains = wnd_at_ah_westend();
+	let wnd_at_rococo_parachains = bridged_wnd_at_ah_rococo();
+	// create foreign WND on AH Rococo
+	create_foreign_on_ah_rococo(wnd_at_rococo_parachains.clone(), true);
+	create_pool_with_native_on!(
+		AssetHubRococo,
+		wnd_at_rococo_parachains.clone(),
+		true,
+		AssetHubRococoSender::get()
+	);
+	// create foreign WND on Penpal Rococo
+	let asset_owner: AccountId = AssetHubRococo::account_id_of(ALICE);
+	PenpalA::force_create_foreign_asset(
+		wnd_at_rococo_parachains.clone(),
+		asset_owner.clone(),
+		true,
+		ASSET_MIN_BALANCE,
+		vec![],
+	);
+	// Configure destination Penpal chain to trust its sibling AH as reserve of bridged WND
+	PenpalA::execute_with(|| {
+		assert_ok!(<PenpalA as Chain>::System::set_storage(
+			<PenpalA as Chain>::RuntimeOrigin::root(),
+			vec![(
+				PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
+				wnd_at_rococo_parachains.encode(),
+			)],
+		));
+	});
+	create_pool_with_native_on!(PenpalA, wnd_at_rococo_parachains.clone(), true, asset_owner);
+
+	Westend::execute_with(|| {
+		let root_origin = <Westend as Chain>::RuntimeOrigin::root();
+		<Westend as WestendPallet>::XcmPallet::force_xcm_version(
+			root_origin,
+			bx!(local_asset_hub.clone()),
+			XCM_VERSION,
+		)
+	})
+	.unwrap();
+	AssetHubRococo::force_xcm_version(
+		AssetHubRococo::sibling_location_of(PenpalA::para_id()),
+		XCM_VERSION,
+	);
+
+	let sov_ahr_on_ahw = AssetHubWestend::sovereign_account_of_parachain_on_other_global_consensus(
+		ByGenesis(ROCOCO_GENESIS_HASH),
+		AssetHubRococo::para_id(),
+	);
+	let wnds_in_reserve_on_ahw_before =
+		<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
+	let sender_wnds_before = <Westend as Chain>::account_data_of(sender.clone()).free;
+	let receiver_wnds_before = PenpalA::execute_with(|| {
+		type Assets = <PenpalA as PenpalAPallet>::ForeignAssets;
+		<Assets as Inspect<_>>::balance(wnd_at_rococo_parachains.clone(), &receiver)
+	});
+
+	// Send WNDs from Westend to AHW over bridge to AHR then onto Penpal parachain
+	{
+		let beneficiary: Location =
+			AccountId32Junction { network: None, id: receiver.clone().into() }.into();
+		// executes on Westend Relay
+		let kusama_xcm = Xcm::<()>(vec![
+			WithdrawAsset((Location::here(), amount).into()),
+			SetFeesMode { jit_withdraw: true },
+			InitiateTeleport {
+				assets: Wild(AllCounted(1)),
+				dest: local_asset_hub,
+				// executes on Westend Asset Hub
+				xcm: Xcm::<()>(vec![
+					BuyExecution {
+						fees: (wnd_at_westend_parachains, amount / 2).into(),
+						weight_limit: Unlimited,
+					},
+					DepositReserveAsset {
+						assets: Wild(AllCounted(1)),
+						dest: asset_hub_rococo_location(),
+						// executes on Rococo Asset Hub
+						xcm: Xcm::<()>(vec![
+							BuyExecution {
+								fees: (wnd_at_rococo_parachains.clone(), amount / 2).into(),
+								weight_limit: Unlimited,
+							},
+							DepositReserveAsset {
+								assets: Wild(AllCounted(1)),
+								dest: AssetHubRococo::sibling_location_of(PenpalA::para_id()),
+								// executes on Rococo Penpal
+								xcm: Xcm::<()>(vec![
+									BuyExecution {
+										fees: (wnd_at_rococo_parachains.clone(), amount / 2).into(),
+										weight_limit: Unlimited,
+									},
+									DepositAsset { assets: Wild(AllCounted(1)), beneficiary },
+								]),
+							},
+						]),
+					},
+				]),
+			},
+		]);
+		send_assets_over_bridge(|| {
+			// send message over bridge
+			assert_ok!(Westend::execute_with(|| {
+				Dmp::<<Westend as Chain>::Runtime>::make_parachain_reachable(
+					AssetHubWestend::para_id(),
+				);
+				let signed_origin = <Westend as Chain>::RuntimeOrigin::signed(WestendSender::get());
+				<Westend as WestendPallet>::XcmPallet::execute(
+					signed_origin,
+					bx!(xcm::VersionedXcm::V5(kusama_xcm.into())),
+					Weight::MAX,
+				)
+			}));
+			AssetHubWestend::execute_with(|| {
+				type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
+				assert_expected_events!(
+					AssetHubWestend,
+					vec![
+						// Amount deposited in AHR's sovereign account
+						RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => {
+							who: *who == sov_ahr_on_ahw.clone().into(),
+						},
+						RuntimeEvent::XcmpQueue(
+							cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
+						) => {},
+					]
+				);
+			});
+		});
+	}
+
+	// process AHR incoming message and check events
+	AssetHubRococo::execute_with(|| {
+		type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			AssetHubRococo,
+			vec![
+				// issue WNDs on AHR
+				RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
+				// message processed successfully
+				RuntimeEvent::MessageQueue(
+					pallet_message_queue::Event::Processed { success: true, .. }
+				) => {},
+			]
+		);
+	});
+	PenpalA::execute_with(|| {
+		PenpalA::assert_xcmp_queue_success(None);
+	});
+
+	let sender_wnds_after = <Westend as Chain>::account_data_of(sender.clone()).free;
+	let receiver_wnds_after = PenpalA::execute_with(|| {
+		type Assets = <PenpalA as PenpalAPallet>::ForeignAssets;
+		<Assets as Inspect<_>>::balance(wnd_at_rococo_parachains, &receiver)
+	});
+	let wnds_in_reserve_on_ahw_after =
+		<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
+
+	// Sender's balance is reduced
+	assert!(sender_wnds_after < sender_wnds_before);
+	// Receiver's balance is increased
+	assert!(receiver_wnds_after > receiver_wnds_before);
+	// Reserve balance is increased by sent amount (less fess)
+	assert!(wnds_in_reserve_on_ahw_after > wnds_in_reserve_on_ahw_before);
+	assert!(wnds_in_reserve_on_ahw_after <= wnds_in_reserve_on_ahw_before + amount);
+}
+
 #[test]
 fn send_back_rocs_from_penpal_westend_through_asset_hub_westend_to_asset_hub_rococo() {
 	let roc_at_westend_parachains = bridged_roc_at_ah_westend();
@@ -429,8 +725,8 @@ fn send_back_rocs_from_penpal_westend_through_asset_hub_westend_to_asset_hub_roc
 
 	// set up ROCs for transfer
 	let penpal_location = AssetHubWestend::sibling_location_of(PenpalB::para_id());
-	let sov_penpal_on_ahr = AssetHubWestend::sovereign_account_id_of(penpal_location);
-	let prefund_accounts = vec![(sov_penpal_on_ahr, amount * 2)];
+	let sov_penpal_on_ahw = AssetHubWestend::sovereign_account_id_of(penpal_location);
+	let prefund_accounts = vec![(sov_penpal_on_ahw, amount * 2)];
 	create_foreign_on_ah_westend(roc_at_westend_parachains.clone(), true, prefund_accounts);
 	let asset_owner: AccountId = AssetHubWestend::account_id_of(ALICE);
 	PenpalB::force_create_foreign_asset(
@@ -543,6 +839,372 @@ fn send_back_rocs_from_penpal_westend_through_asset_hub_westend_to_asset_hub_roc
 	assert!(receiver_rocs_after <= receiver_rocs_before + amount);
 }
 
+#[test]
+fn send_back_rocs_from_penpal_westend_through_asset_hub_westend_to_asset_hub_rococo_to_penpal_rococo(
+) {
+	let roc_at_westend_parachains = bridged_roc_at_ah_westend();
+	let roc_at_rococo_parachains = Location::parent();
+	let amount = ASSET_HUB_WESTEND_ED * 10_000_000;
+	let sender = PenpalBSender::get();
+	let receiver = PenpalAReceiver::get();
+
+	// set up ROCs for transfer
+	let penpal_location = AssetHubWestend::sibling_location_of(PenpalB::para_id());
+	let sov_penpal_on_ahw = AssetHubWestend::sovereign_account_id_of(penpal_location);
+	let prefund_accounts = vec![(sov_penpal_on_ahw.clone(), amount * 2)];
+	create_foreign_on_ah_westend(roc_at_westend_parachains.clone(), true, prefund_accounts);
+	create_pool_with_native_on!(
+		AssetHubWestend,
+		roc_at_westend_parachains.clone(),
+		true,
+		AssetHubRococoSender::get()
+	);
+	let asset_owner: AccountId = AssetHubWestend::account_id_of(ALICE);
+	// Fund WNDs on Westend Penpal
+	PenpalB::mint_foreign_asset(
+		<PenpalB as Chain>::RuntimeOrigin::signed(PenpalAssetOwner::get()),
+		Location::parent(),
+		sender.clone(),
+		amount,
+	);
+	// Create and fund bridged ROCs on Westend Penpal
+	PenpalB::force_create_foreign_asset(
+		roc_at_westend_parachains.clone(),
+		asset_owner.clone(),
+		true,
+		ASSET_MIN_BALANCE,
+		vec![(sender.clone(), amount * 2)],
+	);
+	// Configure source Penpal chain to trust local AH as reserve of bridged ROC
+	PenpalB::execute_with(|| {
+		assert_ok!(<PenpalB as Chain>::System::set_storage(
+			<PenpalB as Chain>::RuntimeOrigin::root(),
+			vec![(
+				PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
+				roc_at_westend_parachains.encode(),
+			)],
+		));
+	});
+
+	// fund the AHW's SA on AHR with the ROC tokens held in reserve
+	let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
+		ByGenesis(WESTEND_GENESIS_HASH),
+		AssetHubWestend::para_id(),
+	);
+	AssetHubRococo::fund_accounts(vec![(sov_ahw_on_ahr.clone(), amount * 2)]);
+
+	// balances before
+	let sender_rocs_before = PenpalB::execute_with(|| {
+		type ForeignAssets = <PenpalB as PenpalBPallet>::ForeignAssets;
+		<ForeignAssets as Inspect<_>>::balance(roc_at_westend_parachains.clone().into(), &sender)
+	});
+	let receiver_rocs_before = PenpalA::execute_with(|| {
+		type Assets = <PenpalA as PenpalAPallet>::ForeignAssets;
+		<Assets as Inspect<_>>::balance(roc_at_rococo_parachains.clone(), &receiver)
+	});
+
+	// send ROCs over the bridge, all fees paid with ROC along the way
+	{
+		let local_asset_hub = PenpalB::sibling_location_of(AssetHubWestend::para_id());
+		let beneficiary: Location =
+			AccountId32Junction { network: None, id: receiver.clone().into() }.into();
+		// executes on Penpal Westend
+		let xcm = Xcm::<()>(vec![
+			WithdrawAsset((roc_at_westend_parachains.clone(), amount).into()),
+			SetFeesMode { jit_withdraw: true },
+			InitiateReserveWithdraw {
+				assets: Wild(AllCounted(1)),
+				reserve: local_asset_hub,
+				// executes on Westend Asset Hub
+				xcm: Xcm::<()>(vec![
+					BuyExecution {
+						fees: (roc_at_westend_parachains.clone(), amount / 2).into(),
+						weight_limit: Unlimited,
+					},
+					InitiateReserveWithdraw {
+						assets: Wild(AllCounted(1)),
+						reserve: asset_hub_rococo_location(),
+						// executes on Rococo Asset Hub
+						xcm: Xcm::<()>(vec![
+							BuyExecution {
+								fees: (roc_at_rococo_parachains.clone(), amount / 2).into(),
+								weight_limit: Unlimited,
+							},
+							DepositReserveAsset {
+								assets: Wild(AllCounted(1)),
+								dest: AssetHubRococo::sibling_location_of(PenpalA::para_id()),
+								// executes on Rococo Penpal
+								xcm: Xcm::<()>(vec![
+									BuyExecution {
+										fees: (roc_at_rococo_parachains.clone(), amount / 2).into(),
+										weight_limit: Unlimited,
+									},
+									DepositAsset { assets: Wild(AllCounted(1)), beneficiary },
+								]),
+							},
+						]),
+					},
+				]),
+			},
+		]);
+		send_assets_over_bridge(|| {
+			// send message over bridge
+			assert_ok!(PenpalB::execute_with(|| {
+				let signed_origin = <PenpalB as Chain>::RuntimeOrigin::signed(sender.clone());
+				<PenpalB as PenpalBPallet>::PolkadotXcm::execute(
+					signed_origin,
+					bx!(xcm::VersionedXcm::V5(xcm.into())),
+					Weight::MAX,
+				)
+			}));
+			AssetHubWestend::execute_with(|| {
+				type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
+				assert_expected_events!(
+					AssetHubWestend,
+					vec![
+						// Amount to reserve transfer is withdrawn from Penpal's sovereign account
+						RuntimeEvent::ForeignAssets(
+							pallet_assets::Event::Burned { asset_id, owner, .. }
+						) => {
+							asset_id: asset_id == &roc_at_westend_parachains,
+							owner: owner == &sov_penpal_on_ahw,
+						},
+						RuntimeEvent::XcmpQueue(
+							cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
+						) => {},
+						// message processed successfully
+						RuntimeEvent::MessageQueue(
+							pallet_message_queue::Event::Processed { success: true, .. }
+						) => {},
+					]
+				);
+			});
+		});
+	}
+
+	// process AHR incoming message and check events
+	AssetHubRococo::execute_with(|| {
+		type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			AssetHubRococo,
+			vec![
+				// burn ROCs from AHW's SA on AHR
+				RuntimeEvent::Balances(
+					pallet_balances::Event::Burned { who, .. }
+				) => {
+					who: *who == sov_ahw_on_ahr.clone().into(),
+				},
+				// sent message to sibling Penpal
+				RuntimeEvent::XcmpQueue(
+					cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
+				) => {},
+				// message processed successfully
+				RuntimeEvent::MessageQueue(
+					pallet_message_queue::Event::Processed { success: true, .. }
+				) => {},
+			]
+		);
+	});
+	PenpalA::execute_with(|| {
+		PenpalA::assert_xcmp_queue_success(None);
+	});
+
+	let sender_rocs_after = PenpalB::execute_with(|| {
+		type ForeignAssets = <PenpalB as PenpalBPallet>::ForeignAssets;
+		<ForeignAssets as Inspect<_>>::balance(roc_at_westend_parachains.into(), &sender)
+	});
+	let receiver_rocs_after = PenpalA::execute_with(|| {
+		type Assets = <PenpalA as PenpalAPallet>::ForeignAssets;
+		<Assets as Inspect<_>>::balance(roc_at_rococo_parachains.clone(), &receiver)
+	});
+
+	// Sender's balance is reduced by sent "amount"
+	assert_eq!(sender_rocs_after, sender_rocs_before - amount);
+	// Receiver's balance is increased by no more than "amount"
+	assert!(receiver_rocs_after > receiver_rocs_before);
+	assert!(receiver_rocs_after <= receiver_rocs_before + amount);
+}
+
+#[test]
+fn send_back_rocs_from_penpal_westend_through_asset_hub_westend_to_asset_hub_rococo_to_rococo_relay(
+) {
+	let roc_at_westend_parachains = bridged_roc_at_ah_westend();
+	let roc_at_rococo_parachains = Location::parent();
+	let amount = ASSET_HUB_WESTEND_ED * 10_000_000;
+	let sender = PenpalBSender::get();
+	let receiver = RococoReceiver::get();
+
+	// set up ROCs for transfer
+	let penpal_location = AssetHubWestend::sibling_location_of(PenpalB::para_id());
+	let sov_penpal_on_ahw = AssetHubWestend::sovereign_account_id_of(penpal_location);
+	let prefund_accounts = vec![(sov_penpal_on_ahw.clone(), amount * 2)];
+	create_foreign_on_ah_westend(roc_at_westend_parachains.clone(), true, prefund_accounts);
+	create_pool_with_native_on!(
+		AssetHubWestend,
+		roc_at_westend_parachains.clone(),
+		true,
+		AssetHubRococoSender::get()
+	);
+	let asset_owner: AccountId = AssetHubWestend::account_id_of(ALICE);
+	// Fund WNDs on Westend Penpal
+	PenpalB::mint_foreign_asset(
+		<PenpalB as Chain>::RuntimeOrigin::signed(PenpalAssetOwner::get()),
+		Location::parent(),
+		sender.clone(),
+		amount,
+	);
+	// Create and fund bridged ROCs on Westend Penpal
+	PenpalB::force_create_foreign_asset(
+		roc_at_westend_parachains.clone(),
+		asset_owner.clone(),
+		true,
+		ASSET_MIN_BALANCE,
+		vec![(sender.clone(), amount * 2)],
+	);
+	// Configure source Penpal chain to trust local AH as reserve of bridged ROC
+	PenpalB::execute_with(|| {
+		assert_ok!(<PenpalB as Chain>::System::set_storage(
+			<PenpalB as Chain>::RuntimeOrigin::root(),
+			vec![(
+				PenpalCustomizableAssetFromSystemAssetHub::key().to_vec(),
+				roc_at_westend_parachains.encode(),
+			)],
+		));
+	});
+
+	// fund the AHW's SA on AHR with the ROC tokens held in reserve
+	let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
+		ByGenesis(WESTEND_GENESIS_HASH),
+		AssetHubWestend::para_id(),
+	);
+	AssetHubRococo::fund_accounts(vec![(sov_ahw_on_ahr.clone(), amount * 2)]);
+
+	// fund Rococo Relay check account so we can teleport back to it
+	Rococo::fund_accounts(vec![(<Rococo as RococoPallet>::XcmPallet::check_account(), amount)]);
+
+	// balances before
+	let sender_rocs_before = PenpalB::execute_with(|| {
+		type ForeignAssets = <PenpalB as PenpalBPallet>::ForeignAssets;
+		<ForeignAssets as Inspect<_>>::balance(roc_at_westend_parachains.clone().into(), &sender)
+	});
+	let receiver_rocs_before = <Rococo as Chain>::account_data_of(receiver.clone()).free;
+
+	// send ROCs over the bridge, all fees paid with ROC along the way
+	{
+		let local_asset_hub = PenpalB::sibling_location_of(AssetHubWestend::para_id());
+		let beneficiary: Location =
+			AccountId32Junction { network: None, id: receiver.clone().into() }.into();
+		// executes on Penpal Westend
+		let xcm = Xcm::<()>(vec![
+			WithdrawAsset((roc_at_westend_parachains.clone(), amount).into()),
+			SetFeesMode { jit_withdraw: true },
+			InitiateReserveWithdraw {
+				assets: Wild(AllCounted(1)),
+				reserve: local_asset_hub,
+				// executes on Westend Asset Hub
+				xcm: Xcm::<()>(vec![
+					BuyExecution {
+						fees: (roc_at_westend_parachains.clone(), amount / 2).into(),
+						weight_limit: Unlimited,
+					},
+					InitiateReserveWithdraw {
+						assets: Wild(AllCounted(1)),
+						reserve: asset_hub_rococo_location(),
+						// executes on Rococo Asset Hub
+						xcm: Xcm::<()>(vec![
+							BuyExecution {
+								fees: (roc_at_rococo_parachains.clone(), amount / 2).into(),
+								weight_limit: Unlimited,
+							},
+							InitiateTeleport {
+								assets: Wild(AllCounted(1)),
+								dest: Location::parent(),
+								// executes on Rococo Relay
+								xcm: Xcm::<()>(vec![
+									BuyExecution {
+										fees: (Location::here(), amount / 2).into(),
+										weight_limit: Unlimited,
+									},
+									DepositAsset { assets: Wild(AllCounted(1)), beneficiary },
+								]),
+							},
+						]),
+					},
+				]),
+			},
+		]);
+		send_assets_over_bridge(|| {
+			// send message over bridge
+			assert_ok!(PenpalB::execute_with(|| {
+				let signed_origin = <PenpalB as Chain>::RuntimeOrigin::signed(sender.clone());
+				<PenpalB as PenpalBPallet>::PolkadotXcm::execute(
+					signed_origin,
+					bx!(xcm::VersionedXcm::V5(xcm.into())),
+					Weight::MAX,
+				)
+			}));
+			AssetHubWestend::execute_with(|| {
+				type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
+				assert_expected_events!(
+					AssetHubWestend,
+					vec![
+						// Amount to reserve transfer is withdrawn from Penpal's sovereign account
+						RuntimeEvent::ForeignAssets(
+							pallet_assets::Event::Burned { asset_id, owner, .. }
+						) => {
+							asset_id: asset_id == &roc_at_westend_parachains,
+							owner: owner == &sov_penpal_on_ahw,
+						},
+						RuntimeEvent::XcmpQueue(
+							cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
+						) => {},
+						// message processed successfully
+						RuntimeEvent::MessageQueue(
+							pallet_message_queue::Event::Processed { success: true, .. }
+						) => {},
+					]
+				);
+			});
+		});
+	}
+
+	// process AHR incoming message and check events
+	AssetHubRococo::execute_with(|| {
+		type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			AssetHubRococo,
+			vec![
+				// burn ROCs from AHW's SA on AHR
+				RuntimeEvent::Balances(
+					pallet_balances::Event::Burned { who, .. }
+				) => {
+					who: *who == sov_ahw_on_ahr.clone().into(),
+				},
+				// sent message to Rococo Relay
+				RuntimeEvent::ParachainSystem(
+					cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
+				) => {},
+				// message processed successfully
+				RuntimeEvent::MessageQueue(
+					pallet_message_queue::Event::Processed { success: true, .. }
+				) => {},
+			]
+		);
+	});
+
+	let sender_rocs_after = PenpalB::execute_with(|| {
+		type ForeignAssets = <PenpalB as PenpalBPallet>::ForeignAssets;
+		<ForeignAssets as Inspect<_>>::balance(roc_at_westend_parachains.into(), &sender)
+	});
+	let receiver_rocs_after = <Rococo as Chain>::account_data_of(receiver.clone()).free;
+
+	// Sender's balance is reduced by sent "amount"
+	assert_eq!(sender_rocs_after, sender_rocs_before - amount);
+	// Receiver's balance is increased by no more than "amount"
+	assert!(receiver_rocs_after > receiver_rocs_before);
+	assert!(receiver_rocs_after <= receiver_rocs_before + amount);
+}
+
 #[test]
 fn dry_run_transfer_to_rococo_sends_xcm_to_bridge_hub() {
 	test_dry_run_transfer_across_pk_bridge!(