diff --git a/src/common/profiler.cpp b/src/common/profiler.cpp
index c37546af0..65c3df167 100644
--- a/src/common/profiler.cpp
+++ b/src/common/profiler.cpp
@@ -6,6 +6,12 @@
 #include "common/profiler_reporting.h"
 #include "common/assert.h"
 
+#if defined(_MSC_VER) && _MSC_VER <= 1800 // MSVC 2013.
+#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h> // For QueryPerformanceCounter/Frequency
+#endif
+
 namespace Common {
 namespace Profiling {
 
@@ -13,6 +19,23 @@ namespace Profiling {
 thread_local Timer* Timer::current_timer = nullptr;
 #endif
 
+#if defined(_MSC_VER) && _MSC_VER <= 1800 // MSVC 2013
+QPCClock::time_point QPCClock::now() {
+    static LARGE_INTEGER freq;
+    // Use this dummy local static to ensure this gets initialized once.
+    static BOOL dummy = QueryPerformanceFrequency(&freq);
+
+    LARGE_INTEGER ticks;
+    QueryPerformanceCounter(&ticks);
+
+    // This is prone to overflow when multiplying, which is why I'm using micro instead of nano. The
+    // correct way to approach this would be to just return ticks as a time_point and then subtract
+    // and do this conversion when creating a duration from two time_points, however, as far as I
+    // could tell the C++ requirements for these types are incompatible with this approach.
+    return time_point(duration(ticks.QuadPart * std::micro::den / freq.QuadPart));
+}
+#endif
+
 TimingCategory::TimingCategory(const char* name, TimingCategory* parent)
         : accumulated_duration(0) {
 
diff --git a/src/common/profiler.h b/src/common/profiler.h
index 53c4f6eaf..3e967b4bc 100644
--- a/src/common/profiler.h
+++ b/src/common/profiler.h
@@ -18,8 +18,26 @@ namespace Profiling {
 #define ENABLE_PROFILING 1
 #endif
 
-using Duration = std::chrono::nanoseconds;
+#if defined(_MSC_VER) && _MSC_VER <= 1800 // MSVC 2013
+// MSVC up to 2013 doesn't use QueryPerformanceCounter for high_resolution_clock, so it has bad
+// precision. We manually implement a clock based on QPC to get good results.
+
+struct QPCClock {
+    using duration = std::chrono::microseconds;
+    using time_point = std::chrono::time_point<QPCClock>;
+    using rep = duration::rep;
+    using period = duration::period;
+    static const bool is_steady = false;
+
+    static time_point now();
+};
+
+using Clock = QPCClock;
+#else
 using Clock = std::chrono::high_resolution_clock;
+#endif
+
+using Duration = Clock::duration;
 
 /**
  * Represents a timing category that measured time can be accounted towards. Should be declared as a