diff --git a/crates/core_arch/src/wasm32/mod.rs b/crates/core_arch/src/wasm32/mod.rs
index e07b361e64..63571bc61b 100644
--- a/crates/core_arch/src/wasm32/mod.rs
+++ b/crates/core_arch/src/wasm32/mod.rs
@@ -31,3 +31,25 @@ pub use self::memory::*;
 pub fn unreachable() -> ! {
     crate::intrinsics::abort()
 }
+
+extern "C" {
+    #[link_name = "llvm.wasm.throw"]
+    fn wasm_throw(tag: i32, ptr: *mut u8) -> !;
+}
+
+/// Generates the [`throw`] instruction from the [exception-handling proposal] for WASM.
+///
+/// This function is unlikely to be stabilized until codegen backends have better support.
+///
+/// [`throw`]: https://webassembly.github.io/exception-handling/core/syntax/instructions.html#syntax-instr-control
+/// [exception-handling proposal]: https://github.com/WebAssembly/exception-handling
+// FIXME: wasmtime does not currently support exception-handling, so cannot execute
+//        a wasm module with the throw instruction in it. once it does, we can
+//        reenable this attribute.
+// #[cfg_attr(test, assert_instr(throw, TAG = 0, ptr = core::ptr::null_mut()))]
+#[inline]
+#[unstable(feature = "wasm_exception_handling_intrinsics", issue = "122465")]
+pub unsafe fn throw<const TAG: i32>(ptr: *mut u8) -> ! {
+    static_assert!(TAG == 0); // LLVM only supports tag 0 == C++ right now.
+    wasm_throw(TAG, ptr)
+}