diff --git a/.gitmodules b/.gitmodules
index ace938e19..00704ec70 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -34,3 +34,6 @@
 [submodule "cubeb"]
     path = externals/cubeb
     url = https://github.com/kinetiknz/cubeb.git
+[submodule "discord-rpc"]
+    path = externals/discord-rpc
+    url = https://github.com/discordapp/discord-rpc.git
diff --git a/.travis/common/travis-ci.env b/.travis/common/travis-ci.env
index 7d63674b4..5fa27a706 100644
--- a/.travis/common/travis-ci.env
+++ b/.travis/common/travis-ci.env
@@ -13,3 +13,4 @@ TRAVIS_TAG
 
 # citra specific flags
 ENABLE_COMPATIBILITY_REPORTING
+USE_DISCORD_PRESENCE
diff --git a/.travis/linux-frozen/docker.sh b/.travis/linux-frozen/docker.sh
index fca1419f6..a4814da1a 100755
--- a/.travis/linux-frozen/docker.sh
+++ b/.travis/linux-frozen/docker.sh
@@ -3,7 +3,7 @@
 cd /citra
 
 mkdir build && cd build
-cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
+cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON
 make -j4
 
 ctest -VV -C Release
diff --git a/.travis/linux/docker.sh b/.travis/linux/docker.sh
index 7828c2b62..2a583d6a5 100755
--- a/.travis/linux/docker.sh
+++ b/.travis/linux/docker.sh
@@ -3,7 +3,7 @@
 cd /citra
 
 mkdir build && cd build
-cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
+cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON
 make -j4
 
 ctest -VV -C Release
diff --git a/.travis/macos/build.sh b/.travis/macos/build.sh
index 281f6b5be..363e88330 100755
--- a/.travis/macos/build.sh
+++ b/.travis/macos/build.sh
@@ -7,7 +7,7 @@ export Qt5_DIR=$(brew --prefix)/opt/qt5
 export PATH="/usr/local/opt/ccache/libexec:$PATH"
 
 mkdir build && cd build
-cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
+cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON
 make -j4
 
 ctest -VV -C Release
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d67916fb..51e66eb7c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,8 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
 
 option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
 
+option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
+
 if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
     message(STATUS "Copying pre-commit hook")
     file(COPY hooks/pre-commit
diff --git a/appveyor.yml b/appveyor.yml
index 6b910b685..f44ab5f43 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -44,9 +44,9 @@ before_build:
         $COMPAT = if ($env:ENABLE_COMPATIBILITY_REPORTING -eq $null) {0} else {$env:ENABLE_COMPATIBILITY_REPORTING}
         if ($env:BUILD_TYPE -eq 'msvc') {
           # redirect stderr and change the exit code to prevent powershell from cancelling the build if cmake prints a warning
-          cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON .. 2>&1 && exit 0'
+          cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON .. 2>&1 && exit 0'
         } else {
-          C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON .. 2>&1"
+          C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON .. 2>&1"
         }
   - cd ..
 
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index fa0136330..139454d69 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -62,6 +62,18 @@ endif()
 add_subdirectory(enet)
 target_include_directories(enet INTERFACE ./enet/include)
 
+# Cubeb
+if (ENABLE_CUBEB)
+    set(BUILD_TESTS OFF CACHE BOOL "")
+    add_subdirectory(cubeb EXCLUDE_FROM_ALL)
+endif()
+
+# DiscordRPC
+if (USE_DISCORD_PRESENCE)
+    add_subdirectory(discord-rpc)
+    target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
+endif()
+
 if (ENABLE_WEB_SERVICE)
     # LibreSSL
     set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
@@ -80,9 +92,3 @@ if (ENABLE_WEB_SERVICE)
     add_library(json-headers INTERFACE)
     target_include_directories(json-headers INTERFACE ./json)
 endif()
-
-# Cubeb
-if(ENABLE_CUBEB)
-    set(BUILD_TESTS OFF CACHE BOOL "")
-    add_subdirectory(cubeb EXCLUDE_FROM_ALL)
-endif()
diff --git a/externals/discord-rpc b/externals/discord-rpc
new file mode 160000
index 000000000..3d3ae7129
--- /dev/null
+++ b/externals/discord-rpc
@@ -0,0 +1 @@
+Subproject commit 3d3ae7129d17643bc706da0a2eea85aafd10ab3a
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index 571a30d7c..fde59da13 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -68,6 +68,7 @@ add_executable(citra-qt
     debugger/registers.h
     debugger/wait_tree.cpp
     debugger/wait_tree.h
+    discord.h
     game_list.cpp
     game_list.h
     game_list_p.h
@@ -201,6 +202,15 @@ target_link_libraries(citra-qt PRIVATE audio_core common core input_common netwo
 target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt5::OpenGL Qt5::Widgets Qt5::Multimedia)
 target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
 
+if (USE_DISCORD_PRESENCE)
+    target_sources(citra-qt PUBLIC
+        discord_impl.cpp
+        discord_impl.h
+    )
+    target_link_libraries(citra-qt PRIVATE discord-rpc)
+    target_compile_definitions(citra-qt PRIVATE -DUSE_DISCORD_PRESENCE)
+endif()
+
 if(UNIX AND NOT APPLE)
     install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
 endif()
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index 3aecc0942..e1cced42d 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -207,6 +207,8 @@ void Config::ReadValues() {
 
     qt_config->beginGroup("UI");
     UISettings::values.theme = ReadSetting("theme", UISettings::themes[0].second).toString();
+    UISettings::values.enable_discord_presence =
+        ReadSetting("enable_discord_presence", true).toBool();
 
     qt_config->beginGroup("Updater");
     UISettings::values.check_for_update_on_start =
@@ -440,6 +442,7 @@ void Config::SaveValues() {
 
     qt_config->beginGroup("UI");
     WriteSetting("theme", UISettings::values.theme, UISettings::themes[0].second);
+    WriteSetting("enable_discord_presence", UISettings::values.enable_discord_presence, true);
 
     qt_config->beginGroup("Updater");
     WriteSetting("check_for_update_on_start", UISettings::values.check_for_update_on_start, true);
diff --git a/src/citra_qt/configuration/configure_web.cpp b/src/citra_qt/configuration/configure_web.cpp
index 78dc81ca3..ff66e45d1 100644
--- a/src/citra_qt/configuration/configure_web.cpp
+++ b/src/citra_qt/configuration/configure_web.cpp
@@ -5,6 +5,7 @@
 #include <QIcon>
 #include <QMessageBox>
 #include "citra_qt/configuration/configure_web.h"
+#include "citra_qt/ui_settings.h"
 #include "core/settings.h"
 #include "core/telemetry_session.h"
 #include "ui_configure_web.h"
@@ -17,6 +18,9 @@ ConfigureWeb::ConfigureWeb(QWidget* parent)
     connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
     connect(this, &ConfigureWeb::LoginVerified, this, &ConfigureWeb::OnLoginVerified);
 
+#ifndef USE_DISCORD_PRESENCE
+    ui->discord_group->setVisible(false);
+#endif
     this->setConfiguration();
 }
 
@@ -49,10 +53,13 @@ void ConfigureWeb::setConfiguration() {
     ui->label_telemetry_id->setText(
         tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
     user_verified = true;
+
+    ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence);
 }
 
 void ConfigureWeb::applyConfiguration() {
     Settings::values.enable_telemetry = ui->toggle_telemetry->isChecked();
+    UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked();
     if (user_verified) {
         Settings::values.citra_username = ui->edit_username->text().toStdString();
         Settings::values.citra_token = ui->edit_token->text().toStdString();
diff --git a/src/citra_qt/configuration/configure_web.ui b/src/citra_qt/configuration/configure_web.ui
index dd996ab62..a8aeda9ad 100644
--- a/src/citra_qt/configuration/configure_web.ui
+++ b/src/citra_qt/configuration/configure_web.ui
@@ -170,6 +170,22 @@
      </item>
     </layout>
    </item>
+   <item>
+     <widget class="QGroupBox" name="discord_group">
+      <property name="title">
+       <string>Discord Presence</string>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout_21">
+       <item>
+        <widget class="QCheckBox" name="toggle_discordrpc">
+         <property name="text">
+          <string>Show Current Game in your Discord Status</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+   </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
diff --git a/src/citra_qt/discord.h b/src/citra_qt/discord.h
new file mode 100644
index 000000000..a867cc4d6
--- /dev/null
+++ b/src/citra_qt/discord.h
@@ -0,0 +1,25 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace DiscordRPC {
+
+class DiscordInterface {
+public:
+    virtual ~DiscordInterface() = default;
+
+    virtual void Pause() = 0;
+    virtual void Update() = 0;
+};
+
+class NullImpl : public DiscordInterface {
+public:
+    ~NullImpl() = default;
+
+    void Pause() override {}
+    void Update() override {}
+};
+
+} // namespace DiscordRPC
diff --git a/src/citra_qt/discord_impl.cpp b/src/citra_qt/discord_impl.cpp
new file mode 100644
index 000000000..138ffaa09
--- /dev/null
+++ b/src/citra_qt/discord_impl.cpp
@@ -0,0 +1,51 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <chrono>
+#include <string>
+#include <discord_rpc.h>
+#include "citra_qt/discord_impl.h"
+#include "citra_qt/ui_settings.h"
+#include "common/common_types.h"
+#include "core/core.h"
+
+namespace DiscordRPC {
+
+DiscordImpl::DiscordImpl() {
+    DiscordEventHandlers handlers{};
+
+    // The number is the client ID for Citra, it's used for images and the
+    // application name
+    Discord_Initialize("461729900748079114", &handlers, 1, nullptr);
+}
+
+DiscordImpl::~DiscordImpl() {
+    Discord_ClearPresence();
+    Discord_Shutdown();
+}
+
+void DiscordImpl::Pause() {
+    Discord_ClearPresence();
+}
+
+void DiscordImpl::Update() {
+    s64 start_time = std::chrono::duration_cast<std::chrono::seconds>(
+                         std::chrono::system_clock::now().time_since_epoch())
+                         .count();
+    std::string title;
+    if (Core::System::GetInstance().IsPoweredOn())
+        Core::System::GetInstance().GetAppLoader().ReadTitle(title);
+    DiscordRichPresence presence{};
+    presence.largeImageKey = "citra_logo";
+    presence.largeImageText = "Citra is an emulator for the Nintendo 3DS";
+    if (Core::System::GetInstance().IsPoweredOn()) {
+        presence.state = title.c_str();
+        presence.details = "Currently in game";
+    } else {
+        presence.details = "Not in game";
+    }
+    presence.startTimestamp = start_time;
+    Discord_UpdatePresence(&presence);
+}
+} // namespace DiscordRPC
diff --git a/src/citra_qt/discord_impl.h b/src/citra_qt/discord_impl.h
new file mode 100644
index 000000000..e714ae6d9
--- /dev/null
+++ b/src/citra_qt/discord_impl.h
@@ -0,0 +1,20 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "citra_qt/discord.h"
+
+namespace DiscordRPC {
+
+class DiscordImpl : public DiscordInterface {
+public:
+    DiscordImpl();
+    ~DiscordImpl();
+
+    void Pause() override;
+    void Update() override;
+};
+
+} // namespace DiscordRPC
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 46ea44be0..8495a83d5 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -34,6 +34,7 @@
 #include "citra_qt/debugger/profiler.h"
 #include "citra_qt/debugger/registers.h"
 #include "citra_qt/debugger/wait_tree.h"
+#include "citra_qt/discord.h"
 #include "citra_qt/game_list.h"
 #include "citra_qt/hotkeys.h"
 #include "citra_qt/main.h"
@@ -58,6 +59,10 @@
 #include "core/loader/loader.h"
 #include "core/settings.h"
 
+#ifdef USE_DISCORD_PRESENCE
+#include "citra_qt/discord_impl.h"
+#endif
+
 #ifdef QT_STATICPLUGIN
 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
 #endif
@@ -120,6 +125,9 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
     default_theme_paths = QIcon::themeSearchPaths();
     UpdateUITheme();
 
+    SetDiscordEnabled(UISettings::values.enable_discord_presence);
+    discord_rpc->Update();
+
     Network::Init();
 
     InitializeWidgets();
@@ -748,6 +756,7 @@ void GMainWindow::BootGame(const QString& filename) {
 }
 
 void GMainWindow::ShutdownGame() {
+    discord_rpc->Pause();
     emu_thread->RequestStop();
 
     // Release emu threads from any breakpoints
@@ -763,6 +772,8 @@ void GMainWindow::ShutdownGame() {
     emu_thread->wait();
     emu_thread = nullptr;
 
+    discord_rpc->Update();
+
     Camera::QtMultimediaCameraHandler::ReleaseHandlers();
 
     // The emulation is stopped, so closing the window or not does not matter anymore
@@ -1049,6 +1060,8 @@ void GMainWindow::OnStartGame() {
     ui.action_Stop->setEnabled(true);
     ui.action_Restart->setEnabled(true);
     ui.action_Report_Compatibility->setEnabled(true);
+
+    discord_rpc->Update();
 }
 
 void GMainWindow::OnPauseGame() {
@@ -1184,11 +1197,14 @@ void GMainWindow::OnConfigure() {
     connect(&configureDialog, &ConfigureDialog::languageChanged, this,
             &GMainWindow::OnLanguageChanged);
     auto old_theme = UISettings::values.theme;
+    const bool old_discord_presence = UISettings::values.enable_discord_presence;
     auto result = configureDialog.exec();
     if (result == QDialog::Accepted) {
         configureDialog.applyConfiguration();
         if (UISettings::values.theme != old_theme)
             UpdateUITheme();
+        if (UISettings::values.enable_discord_presence != old_discord_presence)
+            SetDiscordEnabled(UISettings::values.enable_discord_presence);
         emit UpdateThemedIcons();
         SyncMenuUISettings();
         config->Save();
@@ -1481,6 +1497,19 @@ void GMainWindow::RetranslateStatusBar() {
     multiplayer_state->retranslateUi();
 }
 
+void GMainWindow::SetDiscordEnabled(bool state) {
+#ifdef USE_DISCORD_PRESENCE
+    if (state) {
+        discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>();
+    } else {
+        discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
+    }
+#else
+    discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
+#endif
+    discord_rpc->Update();
+}
+
 #ifdef main
 #undef main
 #endif
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index 90d1f8643..4d35d202f 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -38,6 +38,9 @@ class QProgressBar;
 class RegistersWidget;
 class Updater;
 class WaitTreeWidget;
+namespace DiscordRPC {
+class DiscordInterface;
+}
 
 class GMainWindow : public QMainWindow {
     Q_OBJECT
@@ -61,6 +64,7 @@ public:
     ~GMainWindow();
 
     GameList* game_list;
+    std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
 
 signals:
 
@@ -108,6 +112,7 @@ private:
     void ShowUpdatePrompt();
     void ShowNoUpdatePrompt();
     void CheckForUpdates();
+    void SetDiscordEnabled(bool state);
 
     /**
      * Stores the filename in the recently loaded files list.
diff --git a/src/citra_qt/ui_settings.h b/src/citra_qt/ui_settings.h
index c0743de8e..6b76a52f1 100644
--- a/src/citra_qt/ui_settings.h
+++ b/src/citra_qt/ui_settings.h
@@ -58,6 +58,9 @@ struct Values {
     bool update_on_close;
     bool check_for_update_on_start;
 
+    // Discord RPC
+    bool enable_discord_presence;
+
     QString roms_path;
     QString symbols_path;
     QString game_dir_deprecated;