diff --git a/utils/bazel/llvm-project-overlay/clang-tools-extra/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang-tools-extra/BUILD.bazel
new file mode 100644
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/clang-tools-extra/BUILD.bazel
@@ -0,0 +1,21 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+load("//:vars.bzl", "LLVM_VERSION_MAJOR")
+load("//clang:defs.bzl", "BUILTIN_HEADERS_GEN_DIR")
+load("defs.bzl", "symlink")
+
+package(
+    default_visibility = ["//visibility:public"],
+    features = ["layering_check"],
+)
+
+licenses(["notice"])
+
+symlink(
+    name = "builtin_headers",
+    srcs = ["//clang:builtin_headers_gen"],
+    destination = "lib/clang/{0}/include".format(LLVM_VERSION_MAJOR),
+    partition = BUILTIN_HEADERS_GEN_DIR,
+)
diff --git a/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel
--- a/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel
@@ -369,6 +369,7 @@
 cc_binary(
     name = "clang-tidy",
     srcs = ["tool/ClangTidyToolMain.cpp"],
+    data = ["//clang-tools-extra:builtin_headers"],
     stamp = 0,
     deps = [":tool"],
 )
diff --git a/utils/bazel/llvm-project-overlay/clang-tools-extra/defs.bzl b/utils/bazel/llvm-project-overlay/clang-tools-extra/defs.bzl
new file mode 100644
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/clang-tools-extra/defs.bzl
@@ -0,0 +1,26 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+load("@bazel_skylib//lib:paths.bzl", "paths")
+
+def _symlink_impl(ctx):
+    copied_files = []
+    for input_file in ctx.files.srcs:
+        (_, _, relative_filename) = input_file.path.rpartition(ctx.attr.partition)
+        output_file = ctx.actions.declare_file(paths.join(ctx.attr.destination, relative_filename))
+        ctx.actions.symlink(
+            target_file = input_file,
+            output = output_file,
+        )
+        copied_files.append(output_file)
+    return DefaultInfo(files = depset(copied_files))
+
+symlink = rule(
+    implementation = _symlink_impl,
+    attrs = {
+        "destination": attr.string(mandatory = True),
+        "partition": attr.string(mandatory = True),
+        "srcs": attr.label_list(allow_files = True),
+    },
+)
diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
--- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
@@ -3,10 +3,8 @@
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
-load("//:workspace_root.bzl", "workspace_root")
-load("//llvm:tblgen.bzl", "gentbl")
-load("//llvm:binary_alias.bzl", "binary_alias")
-load("//llvm:cc_plugin_library.bzl", "cc_plugin_library")
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+load("@rules_python//python:defs.bzl", "py_binary")
 load(
     "//:vars.bzl",
     "LLVM_VERSION",
@@ -14,6 +12,11 @@
     "LLVM_VERSION_MINOR",
     "LLVM_VERSION_PATCH",
 )
+load("//:workspace_root.bzl", "workspace_root")
+load("//llvm:binary_alias.bzl", "binary_alias")
+load("//llvm:cc_plugin_library.bzl", "cc_plugin_library")
+load("//llvm:tblgen.bzl", "gentbl")
+load("defs.bzl", "BUILTIN_HEADERS_GEN_DIR")
 
 package(
     default_visibility = ["//visibility:public"],
@@ -1688,14 +1691,17 @@
 genrule(
     name = "builtin_headers_gen",
     srcs = builtin_headers,
-    outs = [hdr.replace("lib/Headers/", "staging/include/") for hdr in builtin_headers],
+    outs = [
+        header.replace("lib/Headers/", BUILTIN_HEADERS_GEN_DIR)
+        for header in builtin_headers
+    ],
     cmd = """
        for src in $(SRCS); do
-         relsrc=$${src#*"$(WORKSPACE_ROOT)"/clang/lib/Headers}
-         target=$(@D)/staging/include/$$relsrc
+         relsrc=$${{src#*"$(WORKSPACE_ROOT)"/clang/lib/Headers}}
+         target=$(@D)/{resource_dir}$$relsrc
          mkdir -p $$(dirname $$target)
          cp $$src $$target
-       done""",
+       done""".format(resource_dir = BUILTIN_HEADERS_GEN_DIR),
     output_to_bindir = 1,
     toolchains = [
         ":workspace_root",
diff --git a/utils/bazel/llvm-project-overlay/clang/defs.bzl b/utils/bazel/llvm-project-overlay/clang/defs.bzl
new file mode 100644
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/clang/defs.bzl
@@ -0,0 +1,5 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+BUILTIN_HEADERS_GEN_DIR = "staging/include/"