diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp
index 8d2380b4cf..5d1207bbe3 100644
--- a/Source/Core/AudioCommon/Mixer.cpp
+++ b/Source/Core/AudioCommon/Mixer.cpp
@@ -11,7 +11,6 @@
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
 #include "Core/HW/AudioInterface.h"
-#include "Core/HW/VideoInterface.h"
 
 // UGLINESS
 #include "Core/PowerPC/PowerPC.h"
@@ -60,11 +59,11 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, boo
 	//advance indexR with sample position
 	//remember fractional offset
 
-	u32 framelimit = SConfig::GetInstance().m_Framelimit;
+	float emulationspeed = SConfig::GetInstance().m_EmulationSpeed;
 	float aid_sample_rate = m_input_sample_rate + offset;
-	if (consider_framelimit && framelimit > 1)
+	if (consider_framelimit && emulationspeed > 0.0f)
 	{
-		aid_sample_rate = aid_sample_rate * (framelimit - 1) * 5 / VideoInterface::TargetRefreshRate;
+		aid_sample_rate = aid_sample_rate * emulationspeed;
 	}
 
 	const u32 ratio = (u32)(65536.0f * aid_sample_rate / (float)m_mixer->m_sampleRate);
diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp
index 0923a3c6c4..ec056558bf 100644
--- a/Source/Core/Core/BootManager.cpp
+++ b/Source/Core/Core/BootManager.cpp
@@ -55,7 +55,7 @@ public:
 	void RestoreConfig(SConfig* config);
 
 	// these store if the relevant setting should be reset back later (true) or if it should be left alone on restore (false)
-	bool bSetFramelimit, bSetEXIDevice[MAX_EXI_CHANNELS], bSetVolume, bSetPads[MAX_SI_CHANNELS], bSetWiimoteSource[MAX_BBMOTES], bSetFrameSkip;
+	bool bSetEmulationSpeed, bSetEXIDevice[MAX_EXI_CHANNELS], bSetVolume, bSetPads[MAX_SI_CHANNELS], bSetWiimoteSource[MAX_BBMOTES], bSetFrameSkip;
 
 private:
 	bool valid, bCPUThread, bSkipIdle, bSyncGPUOnSkipIdleHack, bFPRF, bAccurateNaNs, bMMU, bDCBZOFF, m_EnableJIT,
@@ -64,7 +64,8 @@ private:
 	int iCPUCore, Volume;
 	int iWiimoteSource[MAX_BBMOTES];
 	SIDevices Pads[MAX_SI_CHANNELS];
-	unsigned int framelimit, frameSkip;
+	unsigned int frameSkip;
+	float m_EmulationSpeed;
 	TEXIDevices m_EXIDevice[MAX_EXI_CHANNELS];
 	std::string strBackend, sBackend;
 	std::string m_strGPUDeterminismMode;
@@ -102,7 +103,7 @@ void ConfigCache::SaveConfig(const SConfig& config)
 		Pads[i] = config.m_SIDevice[i];
 	}
 
-	framelimit = config.m_Framelimit;
+	m_EmulationSpeed = config.m_EmulationSpeed;
 	frameSkip = config.m_FrameSkip;
 
 	for (unsigned int i = 0; i < MAX_EXI_CHANNELS; ++i)
@@ -114,7 +115,7 @@ void ConfigCache::SaveConfig(const SConfig& config)
 	sBackend = config.sBackend;
 	m_strGPUDeterminismMode = config.m_strGPUDeterminismMode;
 
-	bSetFramelimit = false;
+	bSetEmulationSpeed = false;
 	std::fill_n(bSetEXIDevice, (int)MAX_EXI_CHANNELS, false);
 	bSetVolume = false;
 	std::fill_n(bSetPads, (int)MAX_SI_CHANNELS, false);
@@ -170,8 +171,8 @@ void ConfigCache::RestoreConfig(SConfig* config)
 			config->m_SIDevice[i] = Pads[i];
 	}
 
-	if (bSetFramelimit)
-		config->m_Framelimit = framelimit;
+	if (bSetEmulationSpeed)
+		config->m_EmulationSpeed = m_EmulationSpeed;
 
 	if (bSetFrameSkip)
 	{
@@ -251,8 +252,8 @@ bool BootCore(const std::string& _rFilename)
 		core_section->Get("HLE_BS2",          &StartUp.bHLE_BS2, StartUp.bHLE_BS2);
 		core_section->Get("ProgressiveScan",  &StartUp.bProgressive, StartUp.bProgressive);
 		core_section->Get("PAL60",            &StartUp.bPAL60, StartUp.bPAL60);
-		if (core_section->Get("FrameLimit",   &SConfig::GetInstance().m_Framelimit, SConfig::GetInstance().m_Framelimit))
-			config_cache.bSetFramelimit = true;
+		if (core_section->Get("EmulationSpeed", &SConfig::GetInstance().m_EmulationSpeed, SConfig::GetInstance().m_EmulationSpeed))
+			config_cache.bSetEmulationSpeed = true;
 		if (core_section->Get("FrameSkip",    &SConfig::GetInstance().m_FrameSkip))
 		{
 			config_cache.bSetFrameSkip = true;
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index db933bceaf..c4a857b82d 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -261,7 +261,7 @@ void SConfig::SaveCoreSettings(IniFile& ini)
 	core->Set("WiimoteEnableSpeaker", m_WiimoteEnableSpeaker);
 	core->Set("RunCompareServer", bRunCompareServer);
 	core->Set("RunCompareClient", bRunCompareClient);
-	core->Set("FrameLimit", m_Framelimit);
+	core->Set("EmulationSpeed", m_EmulationSpeed);
 	core->Set("FrameSkip", m_FrameSkip);
 	core->Set("Overclock", m_OCFactor);
 	core->Set("OverclockEnable", m_OCEnable);
@@ -526,7 +526,7 @@ void SConfig::LoadCoreSettings(IniFile& ini)
 	core->Get("DCBZ",                      &bDCBZOFF,          false);
 	core->Get("FPRF",                      &bFPRF,             false);
 	core->Get("AccurateNaNs",              &bAccurateNaNs,     false);
-	core->Get("FrameLimit",                &m_Framelimit,                                  1); // auto frame limit by default
+	core->Get("EmulationSpeed",            &m_EmulationSpeed,                              1.0f);
 	core->Get("Overclock",                 &m_OCFactor,                                    1.0f);
 	core->Get("OverclockEnable",           &m_OCEnable,                                    false);
 	core->Get("FrameSkip",                 &m_FrameSkip,                                   0);
diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h
index de2be855e8..973f49939a 100644
--- a/Source/Core/Core/ConfigManager.h
+++ b/Source/Core/Core/ConfigManager.h
@@ -196,8 +196,7 @@ struct SConfig : NonCopyable
 
 	// interface language
 	int m_InterfaceLanguage;
-	// framelimit choose
-	unsigned int m_Framelimit;
+	float m_EmulationSpeed;
 	bool m_OCEnable;
 	float m_OCFactor;
 	// other interface settings
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index c49d89c847..b6669b57d2 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -110,7 +110,7 @@ static StoppedCallbackFunc s_on_stopped_callback = nullptr;
 static std::thread s_cpu_thread;
 static bool s_request_refresh_info = false;
 static int s_pause_and_lock_depth = 0;
-static bool s_is_framelimiter_temp_disabled = false;
+static bool s_is_throttler_temp_disabled = false;
 
 #ifdef USE_MEMORYWATCHER
 static std::unique_ptr<MemoryWatcher> s_memory_watcher;
@@ -127,14 +127,14 @@ static void InitIsCPUKey()
 }
 #endif
 
-bool GetIsFramelimiterTempDisabled()
+bool GetIsThrottlerTempDisabled()
 {
-	return s_is_framelimiter_temp_disabled;
+	return s_is_throttler_temp_disabled;
 }
 
-void SetIsFramelimiterTempDisabled(bool disable)
+void SetIsThrottlerTempDisabled(bool disable)
 {
-	s_is_framelimiter_temp_disabled = disable;
+	s_is_throttler_temp_disabled = disable;
 }
 
 std::string GetStateFileName() { return s_state_filename; }
@@ -746,7 +746,7 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock)
 	return wasUnpaused;
 }
 
-// Apply Frame Limit and Display FPS info
+// Display FPS info
 // This should only be called from VI
 void VideoThrottle()
 {
@@ -767,12 +767,12 @@ void VideoThrottle()
 
 // Executed from GPU thread
 // reports if a frame should be skipped or not
-// depending on the framelimit set
+// depending on the emulation speed set
 bool ShouldSkipFrame(int skipped)
 {
-	const u32 TargetFPS = (SConfig::GetInstance().m_Framelimit > 1)
-		? (SConfig::GetInstance().m_Framelimit - 1) * 5
-		: VideoInterface::TargetRefreshRate;
+	u32 TargetFPS = VideoInterface::TargetRefreshRate;
+	if (SConfig::GetInstance().m_EmulationSpeed > 0.0f)
+		TargetFPS = u32(TargetFPS * SConfig::GetInstance().m_EmulationSpeed);
 	const u32 frames = s_drawn_frame.load();
 	const bool fps_slow = !(s_timer.GetTimeDifference() < (frames + skipped) * 1000 / TargetFPS);
 
diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h
index 8389f9e308..e9f179579d 100644
--- a/Source/Core/Core/Core.h
+++ b/Source/Core/Core/Core.h
@@ -24,8 +24,8 @@ extern bool g_aspect_wide;
 
 extern bool g_want_determinism;
 
-bool GetIsFramelimiterTempDisabled();
-void SetIsFramelimiterTempDisabled(bool disable);
+bool GetIsThrottlerTempDisabled();
+void SetIsThrottlerTempDisabled(bool disable);
 
 void Callback_VideoCopiedToXFB(bool video_update);
 
diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp
index 9ef8e45d31..e95d207863 100644
--- a/Source/Core/Core/HW/SystemTimers.cpp
+++ b/Source/Core/Core/HW/SystemTimers.cpp
@@ -195,21 +195,21 @@ static void ThrottleCallback(u64 last_time, int cyclesLate)
 
 	int diff = (u32)last_time - time;
 	const SConfig& config = SConfig::GetInstance();
-	bool frame_limiter = config.m_Framelimit && !Core::GetIsFramelimiterTempDisabled();
+	bool frame_limiter = config.m_EmulationSpeed > 0.0f && !Core::GetIsThrottlerTempDisabled();
 	u32 next_event = GetTicksPerSecond()/1000;
-	if (config.m_Framelimit > 1)
+	if (frame_limiter)
 	{
-		next_event = next_event * (config.m_Framelimit - 1) * 5 / VideoInterface::TargetRefreshRate;
+		if (config.m_EmulationSpeed != 1.0f)
+			next_event = u32(next_event * config.m_EmulationSpeed);
+		const int max_fallback = config.iTimingVariance;
+		if (abs(diff) > max_fallback)
+		{
+			DEBUG_LOG(COMMON, "system too %s, %d ms skipped", diff<0 ? "slow" : "fast", abs(diff) - max_fallback);
+			last_time = time - max_fallback;
+		}
+		else if (diff > 0)
+			Common::SleepCurrentThread(diff);
 	}
-
-	const int max_fallback = config.iTimingVariance;
-	if (frame_limiter && abs(diff) > max_fallback)
-	{
-		DEBUG_LOG(COMMON, "system too %s, %d ms skipped", diff<0 ? "slow" : "fast", abs(diff) - max_fallback);
-		last_time = time - max_fallback;
-	}
-	else if (frame_limiter && diff > 0)
-		Common::SleepCurrentThread(diff);
 	CoreTiming::ScheduleEvent(next_event - cyclesLate, et_Throttle, last_time + 1);
 }
 
diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp
index 8fd54029c5..b838a45fea 100644
--- a/Source/Core/Core/HotkeyManager.cpp
+++ b/Source/Core/Core/HotkeyManager.cpp
@@ -51,8 +51,8 @@ const std::string hotkey_labels[] =
 	_trans("Toggle EFB Copies"),
 	_trans("Toggle Fog"),
 	_trans("Toggle Frame limit"),
-	_trans("Decrease Frame limit"),
-	_trans("Increase Frame limit"),
+	_trans("Decrease Emulation Speed"),
+	_trans("Increase Emulation Speed"),
 
 	_trans("Freelook Decrease Speed"),
 	_trans("Freelook Increase Speed"),
diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h
index d1049c22c5..cb41840457 100644
--- a/Source/Core/Core/HotkeyManager.h
+++ b/Source/Core/Core/HotkeyManager.h
@@ -50,8 +50,8 @@ enum Hotkey
 	HK_TOGGLE_FOG,
 	HK_TOGGLE_THROTTLE,
 
-	HK_DECREASE_FRAME_LIMIT,
-	HK_INCREASE_FRAME_LIMIT,
+	HK_DECREASE_EMULATION_SPEED,
+	HK_INCREASE_EMULATION_SPEED,
 
 	HK_FREELOOK_DECREASE_SPEED,
 	HK_FREELOOK_INCREASE_SPEED,
diff --git a/Source/Core/DolphinWX/Config/GeneralConfigPane.cpp b/Source/Core/DolphinWX/Config/GeneralConfigPane.cpp
index 38485ed79e..0477419fc9 100644
--- a/Source/Core/DolphinWX/Config/GeneralConfigPane.cpp
+++ b/Source/Core/DolphinWX/Config/GeneralConfigPane.cpp
@@ -39,10 +39,9 @@ GeneralConfigPane::GeneralConfigPane(wxWindow* parent, wxWindowID id)
 
 void GeneralConfigPane::InitializeGUI()
 {
-	m_frame_limit_array_string.Add(_("Off"));
-	m_frame_limit_array_string.Add(_("Auto"));
-	for (int i = 5; i <= 120; i += 5) // from 5 to 120
-		m_frame_limit_array_string.Add(wxString::Format("%i", i));
+	m_throttler_array_string.Add(_("Unlimited"));
+	for (int i = 10; i <= 200; i += 10) // from 10% to 200%
+		m_throttler_array_string.Add(wxString::Format("%i%%", i));
 
 	for (const CPUCore& cpu_core : cpu_cores)
 		m_cpu_engine_array_string.Add(cpu_core.name);
@@ -51,31 +50,31 @@ void GeneralConfigPane::InitializeGUI()
 	m_idle_skip_checkbox   = new wxCheckBox(this, wxID_ANY, _("Enable Idle Skipping (speedup)"));
 	m_cheats_checkbox      = new wxCheckBox(this, wxID_ANY, _("Enable Cheats"));
 	m_force_ntscj_checkbox = new wxCheckBox(this, wxID_ANY, _("Force Console as NTSC-J"));
-	m_frame_limit_choice   = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_frame_limit_array_string);
+	m_throttler_choice     = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_throttler_array_string);
 	m_cpu_engine_radiobox  = new wxRadioBox(this, wxID_ANY, _("CPU Emulator Engine"), wxDefaultPosition, wxDefaultSize, m_cpu_engine_array_string, 0, wxRA_SPECIFY_ROWS);
 
 	m_dual_core_checkbox->SetToolTip(_("Splits the CPU and GPU threads so they can be run on separate cores.\nProvides major speed improvements on most modern PCs, but can cause occasional crashes/glitches."));
 	m_idle_skip_checkbox->SetToolTip(_("Attempt to detect and skip wait-loops.\nIf unsure, leave this checked."));
 	m_cheats_checkbox->SetToolTip(_("Enables the use of Action Replay and Gecko cheats."));
 	m_force_ntscj_checkbox->SetToolTip(_("Forces NTSC-J mode for using the Japanese ROM font.\nIf left unchecked, Dolphin defaults to NTSC-U and automatically enables this setting when playing Japanese games."));
-	m_frame_limit_choice->SetToolTip(_("Limits the game speed to the specified number of frames per second (full speed is 60 for NTSC and 50 for PAL)."));
+	m_throttler_choice->SetToolTip(_("Limits the emulation speed to the specified percentage.\nNote that raising or lowering the emulation speed will also raise or lower the audio pitch to prevent audio from stuttering."));
 
 	m_dual_core_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnDualCoreCheckBoxChanged, this);
 	m_idle_skip_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnIdleSkipCheckBoxChanged, this);
 	m_cheats_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnCheatCheckBoxChanged, this);
 	m_force_ntscj_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnForceNTSCJCheckBoxChanged, this);
-	m_frame_limit_choice->Bind(wxEVT_CHOICE, &GeneralConfigPane::OnFrameLimitChoiceChanged, this);
+	m_throttler_choice->Bind(wxEVT_CHOICE, &GeneralConfigPane::OnThrottlerChoiceChanged, this);
 	m_cpu_engine_radiobox->Bind(wxEVT_RADIOBOX, &GeneralConfigPane::OnCPUEngineRadioBoxChanged, this);
 
-	wxBoxSizer* const frame_limit_sizer = new wxBoxSizer(wxHORIZONTAL);
-	frame_limit_sizer->Add(new wxStaticText(this, wxID_ANY, _("Framelimit:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
-	frame_limit_sizer->Add(m_frame_limit_choice, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
+	wxBoxSizer* const throttler_sizer = new wxBoxSizer(wxHORIZONTAL);
+	throttler_sizer->Add(new wxStaticText(this, wxID_ANY, _("Speed Limit:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
+	throttler_sizer->Add(m_throttler_choice, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
 
 	wxStaticBoxSizer* const basic_settings_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Basic Settings"));
 	basic_settings_sizer->Add(m_dual_core_checkbox, 0, wxALL, 5);
 	basic_settings_sizer->Add(m_idle_skip_checkbox, 0, wxALL, 5);
 	basic_settings_sizer->Add(m_cheats_checkbox, 0, wxALL, 5);
-	basic_settings_sizer->Add(frame_limit_sizer);
+	basic_settings_sizer->Add(throttler_sizer);
 
 	wxStaticBoxSizer* const advanced_settings_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Advanced Settings"));
 	advanced_settings_sizer->Add(m_cpu_engine_radiobox, 0, wxALL, 5);
@@ -96,7 +95,9 @@ void GeneralConfigPane::LoadGUIValues()
 	m_idle_skip_checkbox->SetValue(startup_params.bSkipIdle);
 	m_cheats_checkbox->SetValue(startup_params.bEnableCheats);
 	m_force_ntscj_checkbox->SetValue(startup_params.bForceNTSCJ);
-	m_frame_limit_choice->SetSelection(SConfig::GetInstance().m_Framelimit);
+	u32 selection = std::lround(startup_params.m_EmulationSpeed * 10.0f);
+	if (selection < m_throttler_array_string.size())
+		m_throttler_choice->SetSelection(selection);
 
 	for (size_t i = 0; i < cpu_cores.size(); ++i)
 	{
@@ -140,9 +141,10 @@ void GeneralConfigPane::OnForceNTSCJCheckBoxChanged(wxCommandEvent& event)
 	SConfig::GetInstance().bForceNTSCJ = m_force_ntscj_checkbox->IsChecked();
 }
 
-void GeneralConfigPane::OnFrameLimitChoiceChanged(wxCommandEvent& event)
+void GeneralConfigPane::OnThrottlerChoiceChanged(wxCommandEvent& event)
 {
-	SConfig::GetInstance().m_Framelimit = m_frame_limit_choice->GetSelection();
+	if (m_throttler_choice->GetSelection() != wxNOT_FOUND)
+		SConfig::GetInstance().m_EmulationSpeed = m_throttler_choice->GetSelection() * 0.1f;
 }
 
 void GeneralConfigPane::OnCPUEngineRadioBoxChanged(wxCommandEvent& event)
diff --git a/Source/Core/DolphinWX/Config/GeneralConfigPane.h b/Source/Core/DolphinWX/Config/GeneralConfigPane.h
index f431246582..d4394bed87 100644
--- a/Source/Core/DolphinWX/Config/GeneralConfigPane.h
+++ b/Source/Core/DolphinWX/Config/GeneralConfigPane.h
@@ -32,10 +32,10 @@ private:
 	void OnIdleSkipCheckBoxChanged(wxCommandEvent&);
 	void OnCheatCheckBoxChanged(wxCommandEvent&);
 	void OnForceNTSCJCheckBoxChanged(wxCommandEvent&);
-	void OnFrameLimitChoiceChanged(wxCommandEvent&);
+	void OnThrottlerChoiceChanged(wxCommandEvent&);
 	void OnCPUEngineRadioBoxChanged(wxCommandEvent&);
 
-	wxArrayString m_frame_limit_array_string;
+	wxArrayString m_throttler_array_string;
 	wxArrayString m_cpu_engine_array_string;
 
 	wxCheckBox* m_dual_core_checkbox;
@@ -43,7 +43,7 @@ private:
 	wxCheckBox* m_cheats_checkbox;
 	wxCheckBox* m_force_ntscj_checkbox;
 
-	wxChoice* m_frame_limit_choice;
+	wxChoice* m_throttler_choice;
 
 	wxRadioBox* m_cpu_engine_radiobox;
 };
diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp
index 4972bb6b4e..88e3128a78 100644
--- a/Source/Core/DolphinWX/Frame.cpp
+++ b/Source/Core/DolphinWX/Frame.cpp
@@ -1404,16 +1404,30 @@ void CFrame::ParseHotkeys()
 		OSDChoice = 4;
 		g_Config.bDisableFog = !g_Config.bDisableFog;
 	}
-	Core::SetIsFramelimiterTempDisabled(IsHotkey(HK_TOGGLE_THROTTLE, true));
-	if (IsHotkey(HK_DECREASE_FRAME_LIMIT))
+	Core::SetIsThrottlerTempDisabled(IsHotkey(HK_TOGGLE_THROTTLE, true));
+	if (IsHotkey(HK_DECREASE_EMULATION_SPEED))
 	{
-		if (--SConfig::GetInstance().m_Framelimit > 0x19)
-			SConfig::GetInstance().m_Framelimit = 0x19;
+		OSDChoice = 5;
+
+		if (SConfig::GetInstance().m_EmulationSpeed <= 0.0f)
+			SConfig::GetInstance().m_EmulationSpeed = 1.0f;
+		else if (SConfig::GetInstance().m_EmulationSpeed >= 0.2f)
+			SConfig::GetInstance().m_EmulationSpeed -= 0.1f;
+		else
+			SConfig::GetInstance().m_EmulationSpeed = 0.1f;
+
+		if (SConfig::GetInstance().m_EmulationSpeed >= 0.95f && SConfig::GetInstance().m_EmulationSpeed <= 1.05f)
+			SConfig::GetInstance().m_EmulationSpeed = 1.0f;
 	}
-	if (IsHotkey(HK_INCREASE_FRAME_LIMIT))
+	if (IsHotkey(HK_INCREASE_EMULATION_SPEED))
 	{
-		if (++SConfig::GetInstance().m_Framelimit > 0x19)
-			SConfig::GetInstance().m_Framelimit = 0;
+		OSDChoice = 5;
+
+		if (SConfig::GetInstance().m_EmulationSpeed > 0.0f)
+			SConfig::GetInstance().m_EmulationSpeed += 0.1f;
+
+		if (SConfig::GetInstance().m_EmulationSpeed >= 0.95f && SConfig::GetInstance().m_EmulationSpeed <= 1.05f)
+			SConfig::GetInstance().m_EmulationSpeed = 1.0f;
 	}
 	if (IsHotkey(HK_SAVE_STATE_SLOT_SELECTED))
 	{
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 8b8d0aa8f7..c52263843f 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -379,6 +379,8 @@ void Renderer::DrawDebugText()
 			std::string("Aspect Ratio: ") + ar_text + (g_ActiveConfig.bCrop ? " (crop)" : ""),
 			std::string("Copy EFB: ") + efbcopy_text,
 			std::string("Fog: ") + (g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"),
+			SConfig::GetInstance().m_EmulationSpeed <= 0 ? "Speed Limit: Unlimited" :
+			StringFromFormat("Speed Limit: %li%%", std::lround(SConfig::GetInstance().m_EmulationSpeed * 100.f)),
 		};
 
 		enum { lines_count = sizeof(lines) / sizeof(*lines) };
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index 5e3c468d21..626e1f0bd0 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -311,5 +311,5 @@ void VideoConfig::Save(const std::string& ini_file)
 
 bool VideoConfig::IsVSync()
 {
-	return bVSync && !Core::GetIsFramelimiterTempDisabled();
+	return bVSync && !Core::GetIsThrottlerTempDisabled();
 }