diff --git a/src/core/core.cpp b/src/core/core.cpp
index 50d5dab4b..bb268a319 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -421,6 +421,7 @@ struct System::Impl {
     bool is_async_gpu{};
 
     ExecuteProgramCallback execute_program_callback;
+    ExitCallback exit_callback;
 
     std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
     std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{};
@@ -798,6 +799,18 @@ void System::ExecuteProgram(std::size_t program_index) {
     }
 }
 
+void System::RegisterExitCallback(ExitCallback&& callback) {
+    impl->exit_callback = std::move(callback);
+}
+
+void System::Exit() {
+    if (impl->exit_callback) {
+        impl->exit_callback();
+    } else {
+        LOG_CRITICAL(Core, "exit_callback must be initialized by the frontend");
+    }
+}
+
 void System::ApplySettings() {
     if (IsPoweredOn()) {
         Renderer().RefreshBaseSettings();
diff --git a/src/core/core.h b/src/core/core.h
index 715ab88e7..a796472b2 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -387,6 +387,18 @@ public:
      */
     void ExecuteProgram(std::size_t program_index);
 
+    /// Type used for the frontend to designate a callback for System to exit the application.
+    using ExitCallback = std::function<void()>;
+
+    /**
+     * Registers a callback from the frontend for System to exit the application.
+     * @param callback Callback from the frontend to exit the application.
+     */
+    void RegisterExitCallback(ExitCallback&& callback);
+
+    /// Instructs the frontend to exit the application.
+    void Exit();
+
     /// Applies any changes to settings to this core instance.
     void ApplySettings();