diff --git a/cumulus/client/consensus/aura/src/collators/lookahead.rs b/cumulus/client/consensus/aura/src/collators/lookahead.rs
index 322baaa01498cba91e13a067f0472ab57da83cdf..8ac43fbd116e5f14f9c872408cb95bf7604987cd 100644
--- a/cumulus/client/consensus/aura/src/collators/lookahead.rs
+++ b/cumulus/client/consensus/aura/src/collators/lookahead.rs
@@ -36,7 +36,9 @@ use cumulus_client_collator::service::ServiceInterface as CollatorServiceInterfa
 use cumulus_client_consensus_common::{self as consensus_common, ParachainBlockImportMarker};
 use cumulus_client_consensus_proposer::ProposerInterface;
 use cumulus_primitives_aura::AuraUnincludedSegmentApi;
-use cumulus_primitives_core::{ClaimQueueOffset, CollectCollationInfo, PersistedValidationData};
+use cumulus_primitives_core::{
+	ClaimQueueOffset, CollectCollationInfo, PersistedValidationData, DEFAULT_CLAIM_QUEUE_OFFSET,
+};
 use cumulus_relay_chain_interface::RelayChainInterface;
 
 use polkadot_node_primitives::{PoV, SubmitCollationParams};
@@ -260,8 +262,7 @@ where
 				relay_parent,
 				params.para_id,
 				&mut params.relay_client,
-				// Use depth 0, to preserve behaviour.
-				ClaimQueueOffset(0),
+				ClaimQueueOffset(DEFAULT_CLAIM_QUEUE_OFFSET),
 			)
 			.await
 			.get(0)
diff --git a/cumulus/pallets/parachain-system/Cargo.toml b/cumulus/pallets/parachain-system/Cargo.toml
index 66429625d5bfe6fd51ce795a21d59ffbdb2d0bd8..3cb0394c4b95431ca32a6e4e743a0598a54b8e37 100644
--- a/cumulus/pallets/parachain-system/Cargo.toml
+++ b/cumulus/pallets/parachain-system/Cargo.toml
@@ -121,3 +121,5 @@ try-runtime = [
 	"polkadot-runtime-parachains/try-runtime",
 	"sp-runtime/try-runtime",
 ]
+
+experimental-ump-signals = []
diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs
index 21af35fe3de348f4ffaea74f1d5b3750533a4329..a4b505b98e54c4569c46ce33b51a7dc9a97a03c9 100644
--- a/cumulus/pallets/parachain-system/src/lib.rs
+++ b/cumulus/pallets/parachain-system/src/lib.rs
@@ -193,20 +193,46 @@ pub mod ump_constants {
 
 /// Trait for selecting the next core to build the candidate for.
 pub trait SelectCore {
-	fn select_core_for_child() -> (CoreSelector, ClaimQueueOffset);
+	/// Core selector information for the current block.
+	fn selected_core() -> (CoreSelector, ClaimQueueOffset);
+	/// Core selector information for the next block.
+	fn select_next_core() -> (CoreSelector, ClaimQueueOffset);
 }
 
 /// The default core selection policy.
 pub struct DefaultCoreSelector<T>(PhantomData<T>);
 
 impl<T: frame_system::Config> SelectCore for DefaultCoreSelector<T> {
-	fn select_core_for_child() -> (CoreSelector, ClaimQueueOffset) {
+	fn selected_core() -> (CoreSelector, ClaimQueueOffset) {
+		let core_selector: U256 = frame_system::Pallet::<T>::block_number().into();
+
+		(CoreSelector(core_selector.byte(0)), ClaimQueueOffset(DEFAULT_CLAIM_QUEUE_OFFSET))
+	}
+
+	fn select_next_core() -> (CoreSelector, ClaimQueueOffset) {
 		let core_selector: U256 = (frame_system::Pallet::<T>::block_number() + One::one()).into();
 
 		(CoreSelector(core_selector.byte(0)), ClaimQueueOffset(DEFAULT_CLAIM_QUEUE_OFFSET))
 	}
 }
 
+/// Core selection policy that builds on claim queue offset 1.
+pub struct LookaheadCoreSelector<T>(PhantomData<T>);
+
+impl<T: frame_system::Config> SelectCore for LookaheadCoreSelector<T> {
+	fn selected_core() -> (CoreSelector, ClaimQueueOffset) {
+		let core_selector: U256 = frame_system::Pallet::<T>::block_number().into();
+
+		(CoreSelector(core_selector.byte(0)), ClaimQueueOffset(1))
+	}
+
+	fn select_next_core() -> (CoreSelector, ClaimQueueOffset) {
+		let core_selector: U256 = (frame_system::Pallet::<T>::block_number() + One::one()).into();
+
+		(CoreSelector(core_selector.byte(0)), ClaimQueueOffset(1))
+	}
+}
+
 #[frame_support::pallet]
 pub mod pallet {
 	use super::*;
@@ -365,6 +391,11 @@ pub mod pallet {
 				UpwardMessages::<T>::put(&up[..num as usize]);
 				*up = up.split_off(num as usize);
 
+				// Send the core selector UMP signal. This is experimental until relay chain
+				// validators are upgraded to handle ump signals.
+				#[cfg(feature = "experimental-ump-signals")]
+				Self::send_ump_signal();
+
 				// If the total size of the pending messages is less than the threshold,
 				// we decrease the fee factor, since the queue is less congested.
 				// This makes delivery of new messages cheaper.
@@ -1397,9 +1428,9 @@ impl<T: Config> Pallet<T> {
 		}
 	}
 
-	/// Returns the core selector.
+	/// Returns the core selector for the next block.
 	pub fn core_selector() -> (CoreSelector, ClaimQueueOffset) {
-		T::SelectCore::select_core_for_child()
+		T::SelectCore::select_next_core()
 	}
 
 	/// Set a custom head data that should be returned as result of `validate_block`.
@@ -1418,6 +1449,20 @@ impl<T: Config> Pallet<T> {
 		CustomValidationHeadData::<T>::put(head_data);
 	}
 
+	/// Send the ump signals
+	#[cfg(feature = "experimental-ump-signals")]
+	fn send_ump_signal() {
+		use cumulus_primitives_core::relay_chain::vstaging::{UMPSignal, UMP_SEPARATOR};
+
+		UpwardMessages::<T>::mutate(|up| {
+			up.push(UMP_SEPARATOR);
+
+			// Send the core selector signal.
+			let core_selector = T::SelectCore::selected_core();
+			up.push(UMPSignal::SelectCore(core_selector.0, core_selector.1).encode());
+		});
+	}
+
 	/// Open HRMP channel for using it in benchmarks or tests.
 	///
 	/// The caller assumes that the pallet will accept regular outbound message to the sibling
diff --git a/cumulus/primitives/core/src/lib.rs b/cumulus/primitives/core/src/lib.rs
index 6bad65b3ff2c29c11472342e387641162da06204..dfb574ef33018fd138a767e5f2671d38afc32729 100644
--- a/cumulus/primitives/core/src/lib.rs
+++ b/cumulus/primitives/core/src/lib.rs
@@ -335,7 +335,7 @@ pub mod rpsr_digest {
 
 /// The default claim queue offset to be used if it's not configured/accessible in the parachain
 /// runtime
-pub const DEFAULT_CLAIM_QUEUE_OFFSET: u8 = 1;
+pub const DEFAULT_CLAIM_QUEUE_OFFSET: u8 = 0;
 
 /// Information about a collation.
 ///
diff --git a/prdoc/pr_5888.prdoc b/prdoc/pr_5888.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..9552eada691582bc3561300e9189ed620f62444f
--- /dev/null
+++ b/prdoc/pr_5888.prdoc
@@ -0,0 +1,16 @@
+title: 'parachain-system: send core selector ump signal'
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      Send the core selector ump signal in cumulus. Guarded by a compile time feature called `experimental-ump-signals`
+      until nodes are upgraded to a version that includes https://github.com/paritytech/polkadot-sdk/pull/5423 for
+      gracefully handling ump signals.
+
+crates:
+  - name: cumulus-client-consensus-aura
+    bump: minor
+  - name: cumulus-pallet-parachain-system
+    bump: major
+  - name: cumulus-primitives-core
+    bump: minor