diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index c2b7ba0e22..fa4e976f45 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -30,21 +30,19 @@
 EmuThread::EmuThread(GRenderWindow* render_window) :
     exec_cpu_step(false), cpu_running(false), stop_run(false), render_window(render_window) {
 
+    shutdown_event.Reset();
     connect(this, SIGNAL(started()), render_window, SLOT(moveContext()));
 }
 
-void EmuThread::run()
-{
+void EmuThread::run() {
     stop_run = false;
 
     // holds whether the cpu was running during the last iteration,
     // so that the DebugModeLeft signal can be emitted before the
     // next execution step
     bool was_active = false;
-    while (!stop_run)
-    {
-        if (cpu_running)
-        {
+    while (!stop_run) {
+        if (cpu_running) {
             if (!was_active)
                 emit DebugModeLeft();
 
@@ -53,9 +51,7 @@ void EmuThread::run()
             was_active = cpu_running || exec_cpu_step;
             if (!was_active)
                 emit DebugModeEntered();
-        }
-        else if (exec_cpu_step)
-        {
+        } else if (exec_cpu_step) {
             if (!was_active)
                 emit DebugModeLeft();
 
@@ -67,15 +63,14 @@ void EmuThread::run()
             was_active = false;
         }
     }
+
     render_window->moveContext();
 
-    Core::Stop();
+    shutdown_event.Set();
 }
 
-void EmuThread::Stop()
-{
-    if (!isRunning())
-    {
+void EmuThread::Stop() {
+    if (!isRunning()) {
         LOG_WARNING(Frontend, "EmuThread::Stop called while emu thread wasn't running, returning...");
         return;
     }
@@ -88,23 +83,19 @@ void EmuThread::Stop()
 
     // TODO: Waiting here is just a bad workaround for retarded shutdown logic.
     wait(1000);
-    if (isRunning())
-    {
+    if (isRunning()) {
         LOG_WARNING(Frontend, "EmuThread still running, terminating...");
         quit();
 
         // TODO: Waiting 50 seconds can be necessary if the logging subsystem has a lot of spam
         // queued... This should be fixed.
         wait(50000);
-        if (isRunning())
-        {
+        if (isRunning()) {
             LOG_CRITICAL(Frontend, "EmuThread STILL running, something is wrong here...");
             terminate();
         }
     }
     LOG_INFO(Frontend, "EmuThread stopped");
-
-    System::Shutdown();
 }
 
 
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index 8083d275bd..f6f09773c8 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -9,6 +9,7 @@
 
 #include "common/common.h"
 #include "common/emu_window.h"
+#include "common/thread.h"
 
 class QScreen;
 class QKeyEvent;
@@ -37,20 +38,31 @@ public:
     void ExecStep() { exec_cpu_step = true; }
 
     /**
-     * Allow the CPU to continue processing instructions without interruption
+     * Sets whether the CPU is running 
      *
      * @note This function is thread-safe
      */
     void SetCpuRunning(bool running) { cpu_running = running; }
 
     /**
-    * Allow the CPU to continue processing instructions without interruption
-    *
-    * @note This function is thread-safe
-    */
+     * Allow the CPU to continue processing instructions without interruption
+     *
+     * @note This function is thread-safe
+     */
     bool IsCpuRunning() { return cpu_running; }
 
 
+    /**
+     * Shutdown (permantently stops) the CPU
+     */
+    void ShutdownCpu() { stop_run = true; };
+
+    /**
+     * Waits for the CPU shutdown to complete
+     */
+    void WaitForCpuShutdown() { shutdown_event.Wait(); }
+
+
 public slots:
     /**
      * Stop emulation and wait for the thread to finish.
@@ -71,6 +83,8 @@ private:
 
     GRenderWindow* render_window;
 
+    Common::Event shutdown_event;
+
 signals:
     /**
      * Emitted when the CPU has halted execution
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 9f9ebc9189..fe1dac622c 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -57,7 +57,6 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
 
     render_window = new GRenderWindow(this, *this);
     render_window->hide();
-    emu_thread = new EmuThread(render_window);
 
     profilerWidget = new ProfilerWidget(this);
     addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
@@ -197,9 +196,9 @@ void GMainWindow::OnDisplayTitleBars(bool show)
     }
 }
 
-void GMainWindow::BootGame(std::string filename)
-{
+void GMainWindow::BootGame(std::string filename) {
     LOG_INFO(Frontend, "Citra starting...\n");
+
     System::Init(render_window);
 
     // Load a game or die...
@@ -211,6 +210,7 @@ void GMainWindow::BootGame(std::string filename)
     registersWidget->OnDebugModeEntered();
     callstackWidget->OnDebugModeEntered();
 
+    emu_thread = new EmuThread(render_window);
     emu_thread->start();
 
     render_window->show();
@@ -248,14 +248,22 @@ void GMainWindow::OnPauseGame()
     ui.action_Stop->setEnabled(true);
 }
 
-void GMainWindow::OnStopGame()
-{
+void GMainWindow::OnStopGame() {
     emu_thread->SetCpuRunning(false);
-    // TODO: Shutdown core
+
+    emu_thread->ShutdownCpu();
+    emu_thread->WaitForCpuShutdown();
+    emu_thread->Stop();
+
+    delete emu_thread;
+
+    System::Shutdown();
 
     ui.action_Start->setEnabled(true);
     ui.action_Pause->setEnabled(false);
     ui.action_Stop->setEnabled(false);
+
+    render_window->hide();
 }
 
 void GMainWindow::OnOpenHotkeysDialog()