diff --git a/CMakeLists.txt b/CMakeLists.txt
index 099dcc17e0..e6136fe091 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -89,8 +89,13 @@ set(LIBS)
 
 # Set up paths
 set(bindir  ${CMAKE_INSTALL_PREFIX}/bin               CACHE PATH "bindir")
-set(datadir ${CMAKE_INSTALL_PREFIX}/share/dolphin-emu CACHE PATH "datadir")
-set(mandir  ${CMAKE_INSTALL_PREFIX}/share/man         CACHE PATH "mandir")
+if(HAIKU)
+	set(datadir ${CMAKE_INSTALL_PREFIX}/data/dolphin-emu  CACHE PATH "datadir")
+	set(mandir  ${CMAKE_INSTALL_PREFIX}/documentation/man CACHE PATH "mandir")
+else()
+	set(datadir ${CMAKE_INSTALL_PREFIX}/share/dolphin-emu CACHE PATH "datadir")
+	set(mandir  ${CMAKE_INSTALL_PREFIX}/share/man         CACHE PATH "mandir")
+endif()
 add_definitions(-DDATA_DIR="${datadir}/")
 
 if(CMAKE_SYSROOT)
@@ -399,6 +404,10 @@ if(ANDROID)
   SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
   SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
   SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+elseif(HAIKU)
+  set(USE_X11 0)
+  set(USE_UPNP 0)
+  set(USE_EGL 0)
 elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
   list(APPEND LIBS rt)
 endif()
@@ -438,7 +447,7 @@ endif()
 
 set(USE_X11 0)
 
-if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT ENABLE_HEADLESS)
+if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT HAIKU AND NOT ENABLE_HEADLESS)
   find_package(X11)
   if(TRY_X11 AND X11_FOUND)
     set(USE_X11 1)
@@ -808,7 +817,7 @@ if(NOT DISABLE_WX)
     endif()
   endif()
 
-  if(UNIX AND NOT APPLE)
+  if(UNIX AND NOT APPLE AND NOT HAIKU)
     # There is a bug in the FindGTK module in cmake version 2.8.2 that
     # does not find gdk-pixbuf-2.0.  On the other hand some 2.8.3
     # users have complained that pkg-config does not find
diff --git a/Externals/enet/CMakeLists.txt b/Externals/enet/CMakeLists.txt
index 1fe2f1bbf3..24f0396515 100644
--- a/Externals/enet/CMakeLists.txt
+++ b/Externals/enet/CMakeLists.txt
@@ -6,6 +6,11 @@ project(enet)
 include(CheckFunctionExists)
 include(CheckStructHasMember)
 include(CheckTypeSize)
+
+if(HAIKU)
+  set(CMAKE_REQUIRED_LIBRARIES network)
+endif(HAIKU)
+
 check_function_exists("fcntl" HAS_FCNTL)
 check_function_exists("poll" HAS_POLL)
 check_function_exists("getaddrinfo" HAS_GETADDRINFO)
@@ -18,7 +23,11 @@ check_struct_has_member("struct msghdr" "msg_flags" "sys/types.h;sys/socket.h" H
 set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" "sys/socket.h")
 check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
 unset(CMAKE_EXTRA_INCLUDE_FILES)
- 
+
+if(HAIKU)
+  unset(CMAKE_REQUIRED_LIBRARIES)
+endif()
+
 if(HAS_FCNTL)
     add_definitions(-DHAS_FCNTL=1)
 endif()
@@ -49,9 +58,9 @@ endif()
 if(HAS_SOCKLEN_T)
     add_definitions(-DHAS_SOCKLEN_T=1)
 endif()
- 
+
 include_directories(${PROJECT_SOURCE_DIR}/include)
- 
+
 add_library(enet STATIC
         callbacks.c
         compress.c
@@ -63,3 +72,6 @@ add_library(enet STATIC
         unix.c
         win32.c
     )
+if(HAIKU)
+  target_link_libraries(enet network)
+endif(HAIKU)
diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt
index 4e1f21b55f..1718d33ef7 100644
--- a/Source/Core/Common/CMakeLists.txt
+++ b/Source/Core/Common/CMakeLists.txt
@@ -95,6 +95,9 @@ if(WIN32)
   set(SRCS ${SRCS} GL/GLInterface/WGL.cpp)
 elseif(APPLE)
   set(SRCS ${SRCS} GL/GLInterface/AGL.mm)
+elseif(HAIKU)
+  set(SRCS ${SRCS} GL/GLInterface/BGL.cpp)
+  set(LIBS ${LIBS} be GL)
 elseif(USE_X11)
   if (NOT USE_EGL)
     set(SRCS ${SRCS} GL/GLInterface/GLX.cpp)
@@ -115,4 +118,7 @@ add_dolphin_library(common "${SRCS}" "${LIBS}")
 if(UNIX)
   # Posix networking code needs to be fixed for Windows
   add_executable(traversal_server TraversalServer.cpp)
+  if(HAIKU)
+    target_link_libraries(traversal_server network)
+  endif()
 endif()
diff --git a/Source/Core/Common/GL/GLInterface/BGL.cpp b/Source/Core/Common/GL/GLInterface/BGL.cpp
new file mode 100644
index 0000000000..7cc9070a49
--- /dev/null
+++ b/Source/Core/Common/GL/GLInterface/BGL.cpp
@@ -0,0 +1,70 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/GL/GLInterface/BGL.h"
+
+#include <GLView.h>
+#include <Size.h>
+#include <Window.h>
+
+void cInterfaceBGL::Swap()
+{
+  m_gl->SwapBuffers();
+}
+
+bool cInterfaceBGL::Create(void* window_handle, bool core)
+{
+  m_window = static_cast<BWindow*>(window_handle);
+
+  m_gl = new BGLView(m_window->Bounds(), "cInterfaceBGL", B_FOLLOW_ALL_SIDES, 0,
+                     BGL_RGB | BGL_DOUBLE | BGL_ALPHA);
+  m_window->AddChild(m_gl);
+
+  s_opengl_mode = GLInterfaceMode::MODE_OPENGL;
+
+  // Control m_window size and picture scaling
+  BRect size = m_gl->Frame();
+  s_backbuffer_width = size.IntegerWidth();
+  s_backbuffer_height = size.IntegerHeight();
+
+  return true;
+}
+
+bool cInterfaceBGL::MakeCurrent()
+{
+  m_gl->LockGL();
+  return true;
+}
+
+bool cInterfaceBGL::ClearCurrent()
+{
+  m_gl->UnlockGL();
+  return true;
+}
+
+void cInterfaceBGL::Shutdown()
+{
+  // We don't need to delete m_gl, it's owned by the BWindow.
+  m_gl = nullptr;
+}
+
+void cInterfaceBGL::Update()
+{
+  BRect size = m_gl->Frame();
+
+  if (s_backbuffer_width == size.IntegerWidth() && s_backbuffer_height == size.IntegerHeight())
+    return;
+
+  s_backbuffer_width = size.IntegerWidth();
+  s_backbuffer_height = size.IntegerHeight();
+}
+
+void cInterfaceBGL::SwapInterval(int interval)
+{
+}
+
+void* cInterfaceBGL::GetFuncAddress(const std::string& name)
+{
+  return m_gl->GetGLProcAddress(name.c_str());
+}
diff --git a/Source/Core/Common/GL/GLInterface/BGL.h b/Source/Core/Common/GL/GLInterface/BGL.h
new file mode 100644
index 0000000000..aeb678f804
--- /dev/null
+++ b/Source/Core/Common/GL/GLInterface/BGL.h
@@ -0,0 +1,27 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "Common/GL/GLInterfaceBase.h"
+
+class BWindow;
+class BGLView;
+
+class cInterfaceBGL final : public cInterfaceBase
+{
+public:
+  void Swap() override;
+  void* GetFuncAddress(const std::string& name) override;
+  bool Create(void* window_handle, bool core) override;
+  bool MakeCurrent() override;
+  bool ClearCurrent() override;
+  void Shutdown() override;
+  void Update() override;
+  void SwapInterval(int interval) override;
+
+private:
+  BWindow* m_window;
+  BGLView* m_gl;
+};
diff --git a/Source/Core/Common/GL/GLInterface/EGLHaiku.cpp b/Source/Core/Common/GL/GLInterface/EGLHaiku.cpp
new file mode 100644
index 0000000000..253b9c8c98
--- /dev/null
+++ b/Source/Core/Common/GL/GLInterface/EGLHaiku.cpp
@@ -0,0 +1,30 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/GL/GLInterface/EGLHaiku.h"
+
+#include <Window.h>
+
+EGLDisplay cInterfaceEGLHaiku::OpenDisplay()
+{
+  return eglGetDisplay(EGL_DEFAULT_DISPLAY);
+}
+
+EGLNativeWindowType cInterfaceEGLHaiku::InitializePlatform(EGLNativeWindowType host_window,
+                                                           EGLConfig config)
+{
+  EGLint format;
+  eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format);
+
+  BWindow* window = reinterpret_cast<BWindow*>(host_window);
+  const int width = window->Size().width;
+  const int height = window->Size().height;
+  GLInterface->SetBackBufferDimensions(width, height);
+
+  return host_window;
+}
+
+void cInterfaceEGLHaiku::ShutdownPlatform()
+{
+}
diff --git a/Source/Core/Common/GL/GLInterface/EGLHaiku.h b/Source/Core/Common/GL/GLInterface/EGLHaiku.h
new file mode 100644
index 0000000000..fc755963df
--- /dev/null
+++ b/Source/Core/Common/GL/GLInterface/EGLHaiku.h
@@ -0,0 +1,16 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "Common/GL/GLInterface/EGL.h"
+
+class cInterfaceEGLHaiku final : public cInterfaceEGL
+{
+protected:
+  EGLDisplay OpenDisplay() override;
+  EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window,
+                                         EGLConfig config) override;
+  void ShutdownPlatform() override;
+};
diff --git a/Source/Core/Common/GL/GLInterface/GLInterface.cpp b/Source/Core/Common/GL/GLInterface/GLInterface.cpp
index e134544311..edd84cc2ab 100644
--- a/Source/Core/Common/GL/GLInterface/GLInterface.cpp
+++ b/Source/Core/Common/GL/GLInterface/GLInterface.cpp
@@ -20,6 +20,8 @@
 #include "Common/GL/GLInterface/EGL.h"
 #elif ANDROID
 #include "Common/GL/GLInterface/EGLAndroid.h"
+#elif defined(__HAIKU__)
+#include "Common/GL/GLInterface/BGL.h"
 #else
 #error Platform doesnt have a GLInterface
 #endif
@@ -40,6 +42,8 @@ std::unique_ptr<cInterfaceBase> HostGL_CreateGLInterface()
 #endif
 #elif ANDROID
   return std::make_unique<cInterfaceEGLAndroid>();
+#elif defined(__HAIKU__)
+  return std::make_unique<cInterfaceBGL>();
 #else
   return nullptr;
 #endif
diff --git a/Source/Core/Common/MemoryUtil.cpp b/Source/Core/Common/MemoryUtil.cpp
index 5ce39e1052..4eb2e1f2d3 100644
--- a/Source/Core/Common/MemoryUtil.cpp
+++ b/Source/Core/Common/MemoryUtil.cpp
@@ -22,6 +22,8 @@
 #include <sys/types.h>
 #if defined __APPLE__ || defined __FreeBSD__ || defined __OpenBSD__
 #include <sys/sysctl.h>
+#elif defined __HAIKU__
+#include <OS.h>
 #else
 #include <sys/sysinfo.h>
 #endif
@@ -269,6 +271,10 @@ size_t MemPhysical()
   size_t length = sizeof(size_t);
   sysctl(mib, 2, &physical_memory, &length, NULL, 0);
   return physical_memory;
+#elif defined __HAIKU__
+  system_info sysinfo;
+  get_system_info(&sysinfo);
+  return static_cast<size_t>(sysinfo.max_pages * B_PAGE_SIZE);
 #else
   struct sysinfo memInfo;
   sysinfo(&memInfo);
diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp
index d08e98b7ff..da1feb033e 100644
--- a/Source/Core/Common/StringUtil.cpp
+++ b/Source/Core/Common/StringUtil.cpp
@@ -30,7 +30,7 @@
 #include <locale.h>
 #endif
 
-#if !defined(_WIN32) && !defined(ANDROID) && !defined(__OpenBSD__)
+#if !defined(_WIN32) && !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__)
 static locale_t GetCLocale()
 {
   static locale_t c_locale = newlocale(LC_ALL_MASK, "C", nullptr);
@@ -123,11 +123,11 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar
     c_locale = _create_locale(LC_ALL, "C");
   writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args);
 #else
-#if !defined(ANDROID) && !defined(__OpenBSD__)
+#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__)
   locale_t previousLocale = uselocale(GetCLocale());
 #endif
   writtenCount = vsnprintf(out, outsize, format, args);
-#if !defined(ANDROID) && !defined(__OpenBSD__)
+#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__)
   uselocale(previousLocale);
 #endif
 #endif
@@ -164,12 +164,12 @@ std::string StringFromFormatV(const char* format, va_list args)
   std::string temp = buf;
   delete[] buf;
 #else
-#if !defined(ANDROID) && !defined(__OpenBSD__)
+#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__)
   locale_t previousLocale = uselocale(GetCLocale());
 #endif
   if (vasprintf(&buf, format, args) < 0)
     ERROR_LOG(COMMON, "Unable to allocate memory for string");
-#if !defined(ANDROID) && !defined(__OpenBSD__)
+#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__)
   uselocale(previousLocale);
 #endif
 
diff --git a/Source/Core/Common/Thread.cpp b/Source/Core/Common/Thread.cpp
index 909016e7ae..190653ee31 100644
--- a/Source/Core/Common/Thread.cpp
+++ b/Source/Core/Common/Thread.cpp
@@ -16,6 +16,8 @@
 #include <mach/mach.h>
 #elif defined BSD4_4 || defined __FreeBSD__ || defined __OpenBSD__
 #include <pthread_np.h>
+#elif defined __HAIKU__
+#include <OS.h>
 #endif
 
 #ifdef USE_VTUNE
@@ -136,6 +138,8 @@ void SetCurrentThreadName(const char* szThreadName)
   pthread_setname_np(szThreadName);
 #elif defined __FreeBSD__ || defined __OpenBSD__
   pthread_set_name_np(pthread_self(), szThreadName);
+#elif defined __HAIKU__
+  rename_thread(find_thread(nullptr), szThreadName);
 #else
   // linux doesn't allow to set more than 16 bytes, including \0.
   pthread_setname_np(pthread_self(), std::string(szThreadName).substr(0, 15).c_str());
diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp
index 0a73305962..caf67861ca 100644
--- a/Source/Core/Core/IOS/Network/Socket.cpp
+++ b/Source/Core/Core/IOS/Network/Socket.cpp
@@ -8,6 +8,9 @@
 #include <arpa/inet.h>
 #include <unistd.h>
 #endif
+#ifdef __HAIKU__
+#include <sys/select.h>
+#endif
 
 #include "Common/FileUtil.h"
 #include "Core/ConfigManager.h"
@@ -162,8 +165,12 @@ s32 WiiSocket::CloseFd()
 
 s32 WiiSocket::FCntl(u32 cmd, u32 arg)
 {
+#ifndef F_GETFL
 #define F_GETFL 3
+#endif
+#ifndef F_SETFL
 #define F_SETFL 4
+#endif
 #define F_NONBLOCK 4
   s32 ret = 0;
   if (cmd == F_GETFL)
diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h
index e923e8d27e..acacf48c82 100644
--- a/Source/Core/Core/IOS/Network/Socket.h
+++ b/Source/Core/Core/IOS/Network/Socket.h
@@ -15,13 +15,13 @@ typedef pollfd pollfd_t;
 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
 #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
 
-#elif defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__)
+#elif defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__) or defined(__HAIKU__)
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
-#if defined(ANDROID)
+#if defined(ANDROID) || defined(__HAIKU__)
 #include <fcntl.h>
 #else
 #include <sys/fcntl.h>
diff --git a/Source/Core/Core/MachineContext.h b/Source/Core/Core/MachineContext.h
index 891f5c2e15..a2658c0006 100644
--- a/Source/Core/Core/MachineContext.h
+++ b/Source/Core/Core/MachineContext.h
@@ -188,6 +188,30 @@ typedef mcontext_t SContext;
 #else
 #error No context definition for architecture
 #endif
+#elif defined(__HAIKU__)
+#include <signal.h>
+typedef mcontext_t SContext;
+#if _M_X86_64
+#define CTX_RAX rax
+#define CTX_RBX rbx
+#define CTX_RCX rcx
+#define CTX_RDX rdx
+#define CTX_RDI rdi
+#define CTX_RSI rsi
+#define CTX_RBP rbp
+#define CTX_RSP rsp
+#define CTX_R8 r8
+#define CTX_R9 r9
+#define CTX_R10 r10
+#define CTX_R11 r11
+#define CTX_R12 r12
+#define CTX_R13 r13
+#define CTX_R14 r14
+#define CTX_R15 r15
+#define CTX_RIP rip
+#else
+#error No context definition for machine
+#endif
 #else
 #error No context definition for OS
 #endif
diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp
index 700558541c..a77a6657bf 100644
--- a/Source/Core/Core/NetPlayServer.cpp
+++ b/Source/Core/Core/NetPlayServer.cpp
@@ -21,7 +21,10 @@
 #if !defined(_WIN32)
 #include <sys/socket.h>
 #include <sys/types.h>
-#ifndef ANDROID
+#ifdef __HAIKU__
+#define _BSD_SOURCE
+#include <bsd/ifaddrs.h>
+#elif !defined ANDROID
 #include <ifaddrs.h>
 #endif
 #include <arpa/inet.h>
diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp
index 6d7852fa47..9d4cb69614 100644
--- a/Source/Core/VideoCommon/DriverDetails.cpp
+++ b/Source/Core/VideoCommon/DriverDetails.cpp
@@ -35,6 +35,8 @@ const u32 m_os = OS_ALL | OS_LINUX;
 const u32 m_os = OS_ALL | OS_FREEBSD;
 #elif __OpenBSD__
 const u32 m_os = OS_ALL | OS_OPENBSD;
+#elif __HAIKU__
+const u32 m_os = OS_ALL | OS_HAIKU;
 #endif
 
 static API m_api = API_OPENGL;
diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h
index dc3340c024..44e492b3a2 100644
--- a/Source/Core/VideoCommon/DriverDetails.h
+++ b/Source/Core/VideoCommon/DriverDetails.h
@@ -27,6 +27,7 @@ enum OS
   OS_ANDROID = (1 << 4),
   OS_FREEBSD = (1 << 5),
   OS_OPENBSD = (1 << 6),
+  OS_HAIKU = (1 << 7),
 };
 // Enum of known vendors
 // Tegra and Nvidia are separated out due to such substantial differences