diff --git a/Makefile b/Makefile
index 369c28fe2f75bf8be8bf6b6ec53b584d67127e5d..15b726d9d4c282107bf40071c1ca789423d4f61c 100644
--- a/Makefile
+++ b/Makefile
@@ -78,6 +78,10 @@ PHONY: iwyu
 iwyu: all
 	$(NINJA) -C build $@
 
+PHONY: fix-includes
+fix-includes: all
+	./tools/fix-includes
+
 stresstest: test
 	./stresstest/stresstest.sh build/tests/simplest_fib_test
 
diff --git a/tools/fix-includes b/tools/fix-includes
new file mode 100755
index 0000000000000000000000000000000000000000..225adaf8377a788e161a82df9c72f8f74dac561b
--- /dev/null
+++ b/tools/fix-includes
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Pretty fancy method to get reliable the absolute path of a shell
+# script, *even if it is sourced*. Credits go to GreenFox on
+# stackoverflow: http://stackoverflow.com/a/12197518/194894
+pushd . > /dev/null
+SCRIPTDIR="${BASH_SOURCE[0]}";
+while([ -h "${SCRIPTDIR}" ]); do
+    cd "`dirname "${SCRIPTDIR}"`"
+    SCRIPTDIR="$(readlink "`basename "${SCRIPTDIR}"`")";
+done
+cd "`dirname "${SCRIPTDIR}"`" > /dev/null
+SCRIPTDIR="`pwd`";
+popd  > /dev/null
+
+echoerr() { echo "$@" 1>&2; }
+
+DEBUG=false
+while getopts d OPT; do
+	case $OPT in
+		d)
+			set -x
+			DEBUG=true
+			;;
+		*)
+			echo "usage: ${0##*/} [-dq} [--] ARGS..."
+			exit 2
+	esac
+done
+shift $(( OPTIND - 1 ))
+OPTIND=1
+
+ROOTDIR=$(readlink -f "${SCRIPTDIR}/..")
+
+BUILDDIR="${ROOTDIR}/build"
+
+if [[ ! -L "${BUILDDIR}" ]]; then
+	echoerr "ERROR: ${BUILDDIR} does not exist (or is not a symlink)"
+	exit 1
+fi
+
+cleanup() {
+	if $DEBUG; then
+		echo "Debug activated, preserving temporary files"
+		echo "TMPFILE=${TMPFILE}"
+		return
+	fi
+
+	rm "${TMPFILE}"
+}
+
+TMPFILE="$(mktemp)"
+trap cleanup exit
+
+cd "${BUILDDIR}"
+
+echo "Running IWYU"
+ninja iwyu > "${TMPFILE}"
+
+echo "Running fix_includes.py"
+fix_includes.py < "${TMPFILE}"
+
+cd "${ROOTDIR}"
+
+# Run Clang format afterwards.
+make format