diff --git a/CMakeLists.txt b/CMakeLists.txt
index f5364bc8853e2d2bafc0a0a03b7a7c8710eac503..58bbf9df09f52a6bcd2c1227a653be3e1d356f0e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,6 +49,9 @@ else()
 	set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT OFF)
 endif()
 
+if("${CMAKE_SYSTEM_NAME}" MATCHES Linux)
+	option(SRB2_CONFIG_ENABLE_VALGRIND "Build with Valgrind memory debugging support" OFF)
+endif()
 option(
 	SRB2_CONFIG_SYSTEM_LIBRARIES
 	"Link dependencies using CMake's find_package and do not use internal builds"
diff --git a/cmake/Modules/FindValgrind.cmake b/cmake/Modules/FindValgrind.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4e4fe99019869812fd9fd558bd37de8be0895a7c
--- /dev/null
+++ b/cmake/Modules/FindValgrind.cmake
@@ -0,0 +1,56 @@
+# Find Valgrind
+# Once done, this will define
+#
+#  VALGRIND_FOUND - system has Valgrind
+#  VALGRIND_INCLUDE_DIRS - Valgrind include directories
+#  VALGRIND_LIBRARIES - link libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(VALGRIND_PKGCONF valgrind)
+
+# includes
+find_path(VALGRIND_INCLUDE_DIR
+	NAMES valgrind.h
+	PATHS
+		${VALGRIND_PKGCONF_INCLUDE_DIRS}
+		"/usr/include/valgrind"
+		"/usr/local/include/valgrind"
+)
+
+# library
+find_library(COREGRIND_LIBRARY
+	NAMES coregrind
+	PATHS
+		${VALGRIND_PKGCONF_LIBRARY_DIRS}
+		"/usr/lib/valgrind"
+		"/usr/local/lib/valgrind"
+)
+find_library(VEX_LIBRARY
+	NAMES vex
+	PATHS
+		${VALGRIND_PKGCONF_LIBRARY_DIRS}
+		"/usr/lib/valgrind"
+		"/usr/local/lib/valgrind"
+)
+
+# set include dir variables
+set(VALGRIND_PROCESS_INCLUDES VALGRIND_INCLUDE_DIR)
+set(VALGRIND_PROCESS_LIBS COREGRIND_LIBRARY VEX_LIBRARY)
+libfind_process(VALGRIND)
+
+if(VALGRIND_FOUND AND NOT TARGET Valgrind::Valgrind)
+	add_library(Valgrind::Coregrind UNKNOWN IMPORTED)
+	set_target_properties(Valgrind::Coregrind PROPERTIES
+		IMPORTED_LOCATION "${COREGRIND_LIBRARY}"
+	)
+	add_library(Valgrind::Vex UNKNOWN IMPORTED)
+	set_target_properties(Valgrind::Vex PROPERTIES
+		IMPORTED_LOCATION "${VEX_LIBRARY}"
+	)
+	add_library(Valgrind::Valgrind UNKNOWN IMPORTED)
+	set_target_properties(Valgrind::Valgrind PROPERTIES
+		INTERFACE_INCLUDE_DIRECTORIES "${VALGRIND_INCLUDE_DIR}"
+	)
+	target_link_libraries(Valgrind::Valgrind PUBLIC Valgrind::Coregrind Valgrind::Vex)
+endif()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2c98019e80bc50a15f5727eb79c756524706b195..90becd6eb7d34a026d55cbc74f92dac1bc96e7df 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -140,6 +140,11 @@ if(${SRB2_CONFIG_DEV_BUILD})
 endif()
 target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
 
+if("${SRB2_CONFIG_ENABLE_VALGRIND}" AND "${CMAKE_SYSTEM_NAME}" MATCHES Linux)
+	find_package(Valgrind REQUIRED)
+	target_link_libraries(SRB2SDL2 PRIVATE Valgrind::Valgrind)
+endif()
+
 add_subdirectory(sdl)
 
 # strip debug symbols into separate file when using gcc.