diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7adfb462337d73520e9924b572e47776d6471f22..a633b94826072f9a0aa13f488abf9249486fe893 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,6 +35,7 @@ find_package(SDL2)
 find_package(Threads)
 find_package(ZLIB)
 find_package(cJSON)
+find_package(Systemd)
 
 # @TODO Turn into a find_package LIBUVC file.
 pkg_check_modules(LIBUVC libuvc)
@@ -72,6 +73,7 @@ cmake_dependent_option(BUILD_WITH_EGL "Enable OpenGL on EGL Graphics API support
 cmake_dependent_option(BUILD_WITH_DBUS "Enable dbus support (for BLE support)" ON "DBUS_FOUND" OFF)
 cmake_dependent_option(BUILD_COMPOSITOR_MAIN "Build main compositor host" ON "BUILD_WITH_WAYLAND OR BUILD_WITH_XCB" OFF)
 cmake_dependent_option(XRT_BUILD_IPC "Build OpenXR runtime target" ON "BUILD_COMPOSITOR_MAIN" OFF)
+cmake_dependent_option(XRT_HAVE_SYSTEMD "Enable systemd support (for socket activation of service)" ON "Systemd_FOUND AND XRT_BUILD_IPC" OFF)
 cmake_dependent_option(BUILD_TARGET_OPENXR "Build OpenXR runtime target" ON "BUILD_COMPOSITOR_MAIN OR XRT_BUILD_IPC" OFF)
 
 # Most users won't touch these.
diff --git a/cmake/FindSystemd.cmake b/cmake/FindSystemd.cmake
index 09d60115035a0ec1852dd2db8003f0aadcb5e05a..2daf9a74e8584a3547e2d792fd0e2a3388846096 100644
--- a/cmake/FindSystemd.cmake
+++ b/cmake/FindSystemd.cmake
@@ -15,6 +15,7 @@
 #
 #=============================================================================
 # Copyright (c) 2015 Jari Vetoniemi
+# Copyright (c) 2020 Collabora, Ltd.
 #
 # Distributed under the OSI-approved BSD License (the "License");
 #
@@ -24,17 +25,25 @@
 #=============================================================================
 
 include(FeatureSummary)
-set_package_properties(Systemd PROPERTIES
-   URL "http://freedesktop.org/wiki/Software/systemd/"
-   DESCRIPTION "System and Service Manager")
+set_package_properties(
+    Systemd PROPERTIES
+    URL "http://freedesktop.org/wiki/Software/systemd/"
+    DESCRIPTION "System and Service Manager")
 
 find_package(PkgConfig)
 pkg_check_modules(PC_SYSTEMD QUIET libsystemd)
-find_library(SYSTEMD_LIBRARIES NAMES systemd ${PC_SYSTEMD_LIBRARY_DIRS})
-find_path(SYSTEMD_INCLUDE_DIRS systemd/sd-login.h HINTS ${PC_SYSTEMD_INCLUDE_DIRS})
-
-set(SYSTEMD_DEFINITIONS ${PC_SYSTEMD_CFLAGS_OTHER})
+find_library(
+    SYSTEMD_LIBRARY
+    NAMES systemd
+    HINTS ${PC_SYSTEMD_LIBRARY_DIRS})
+find_path(SYSTEMD_INCLUDE_DIR systemd/sd-login.h
+          HINTS ${PC_SYSTEMD_INCLUDE_DIRS})
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(SYSTEMD DEFAULT_MSG SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES)
-mark_as_advanced(SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES SYSTEMD_DEFINITIONS)
+find_package_handle_standard_args(Systemd DEFAULT_MSG SYSTEMD_INCLUDE_DIR
+                                  SYSTEMD_LIBRARY)
+if(SYSTEMD_FOUND)
+    set(SYSTEMD_LIBRARIES ${SYSTEMD_LIBRARY})
+    set(SYSTEMD_INCLUDE_DIRS ${SYSTEMD_INCLUDE_DIR})
+    set(SYSTEMD_DEFINITIONS ${PC_SYSTEMD_CFLAGS_OTHER})
+endif()
diff --git a/src/xrt/include/xrt/xrt_config_have.h.cmake_in b/src/xrt/include/xrt/xrt_config_have.h.cmake_in
index dbff3c9952d48749d0451c8de4d442f6b652cd81..1feecbb6e575922eb62a1f78f466a2c509dd6ae0 100644
--- a/src/xrt/include/xrt/xrt_config_have.h.cmake_in
+++ b/src/xrt/include/xrt/xrt_config_have.h.cmake_in
@@ -26,3 +26,5 @@
 #cmakedefine XRT_HAVE_SDL2
 
 #cmakedefine XRT_HAVE_OPENHMD
+
+#cmakedefine XRT_HAVE_SYSTEMD
diff --git a/src/xrt/ipc/CMakeLists.txt b/src/xrt/ipc/CMakeLists.txt
index f0f5fd1e8dce249c3f85265372de5346334e1451..0dc4bda2f39013430f42fe3aa0d8344bf4d335dc 100644
--- a/src/xrt/ipc/CMakeLists.txt
+++ b/src/xrt/ipc/CMakeLists.txt
@@ -75,3 +75,10 @@ target_link_libraries(ipc_server PRIVATE
 	aux_util
 	rt
 	)
+
+if(XRT_HAVE_SYSTEMD)
+	target_include_directories(ipc_server PRIVATE
+		${SYSTEMD_INCLUDE_DIRS})
+	target_link_libraries(ipc_server PRIVATE
+		${SYSTEMD_LIBRARIES})
+endif()
diff --git a/src/xrt/ipc/ipc_server.h b/src/xrt/ipc/ipc_server.h
index 55610201faa44657aa168234ed592555fb4f7df1..a51387720e3100233e81b9d8a8c76ed44ca0d199 100644
--- a/src/xrt/ipc/ipc_server.h
+++ b/src/xrt/ipc/ipc_server.h
@@ -156,6 +156,9 @@ struct ipc_server
 	// Should we exit when a client disconnects.
 	bool exit_on_disconnect;
 
+	//! Were we launched by socket activation, instead of explicitly?
+	bool launched_by_socket;
+
 	bool print_debug;
 	bool print_spew;
 
diff --git a/src/xrt/ipc/ipc_server_process.c b/src/xrt/ipc/ipc_server_process.c
index b7ed653daaef7c5887fa99281bc1585071acb689..baa3e26d2d5292076f2b661c20de98dc2d8c794e 100644
--- a/src/xrt/ipc/ipc_server_process.c
+++ b/src/xrt/ipc/ipc_server_process.c
@@ -12,6 +12,7 @@
 #include "xrt/xrt_device.h"
 #include "xrt/xrt_instance.h"
 #include "xrt/xrt_compositor.h"
+#include "xrt/xrt_config_have.h"
 
 #include "util/u_var.h"
 #include "util/u_misc.h"
@@ -36,6 +37,9 @@
 #include <errno.h>
 #include <stdio.h>
 
+#ifdef XRT_HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
 
 /*
  *
@@ -68,6 +72,7 @@ teardown_all(struct ipc_server *s)
 	xrt_instance_destroy(&s->xinst);
 
 	if (s->listen_socket > 0) {
+		// Close socket on exit
 		close(s->listen_socket);
 		s->listen_socket = -1;
 	}
@@ -174,8 +179,28 @@ init_shm(struct ipc_server *s)
 }
 
 static int
-init_listen_socket(struct ipc_server *s)
+get_systemd_socket(struct ipc_server *s, int *out_fd)
+{
+#ifdef XRT_HAVE_SYSTEMD
+	// We may have been launched with socket activation
+	int num_fds = sd_listen_fds(0);
+	if (num_fds > 1) {
+		fprintf(stderr,
+		        "Too many file descriptors passed by systemd.\n");
+		return -1;
+	}
+	if (num_fds == 1) {
+		*out_fd = SD_LISTEN_FDS_START + 0;
+		s->launched_by_socket = true;
+		printf("Got existing socket from systemd.\n");
+	}
+#endif
+	return 0;
+}
+static int
+create_listen_socket(struct ipc_server *s, int *out_fd)
 {
+	// no fd provided
 	struct sockaddr_un addr;
 	int fd, ret;
 
@@ -202,9 +227,31 @@ init_listen_socket(struct ipc_server *s)
 		close(fd);
 		return ret;
 	}
+	printf("Created listening socket.\n");
+	*out_fd = fd;
+	return 0;
+}
+
+static int
+init_listen_socket(struct ipc_server *s)
+{
+	int fd = -1, ret;
+	s->listen_socket = -1;
+
+	ret = get_systemd_socket(s, &fd);
+	if (ret < 0) {
+		return ret;
+	}
 
+	if (fd == -1) {
+		ret = create_listen_socket(s, &fd);
+		if (ret < 0) {
+			return ret;
+		}
+	}
 	// All ok!
 	s->listen_socket = fd;
+	printf("Listening socket is fd %d\n", s->listen_socket);
 
 	return fd;
 }
@@ -221,12 +268,17 @@ init_epoll(struct ipc_server *s)
 
 	struct epoll_event ev = {0};
 
-	ev.events = EPOLLIN;
-	ev.data.fd = 0; // stdin
-	ret = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, 0, &ev);
-	if (ret < 0) {
-		fprintf(stderr, "ERROR: epoll_ctl(stdin) failed '%i'\n", ret);
-		return ret;
+	if (!s->launched_by_socket) {
+		// Can't do this when launched by systemd socket activation by
+		// default
+		ev.events = EPOLLIN;
+		ev.data.fd = 0; // stdin
+		ret = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, 0, &ev);
+		if (ret < 0) {
+			fprintf(stderr, "ERROR: epoll_ctl(stdin) failed '%i'\n",
+			        ret);
+			return ret;
+		}
 	}
 
 	ev.events = EPOLLIN;