1diff --git b/android/bindgen_modules.bp a/android/bindgen_modules.bp
2new file mode 100644
3index 0000000..c9a3f45
4--- /dev/null
5+++ a/android/bindgen_modules.bp
6@@ -0,0 +1,21 @@
7+rust_binary_host {
8+    name: "libbpf_bindgen_build",
9+    host_cross_supported: false,
10+    srcs: ["android/build.rs"],
11+    rustlibs: [
12+        "libbindgen",
13+        "libbindgen_cmd",
14+    ],
15+    lints: "android",
16+    clippy_lints: "android",
17+}
18+
19+rust_bindgen {
20+    name: "liblibbpf_bindgen",
21+    crate_name: "libbpf_bindgen",
22+    custom_bindgen: "libbpf_bindgen_build",
23+    wrapper_src: "android/libbpf_wrapper.h",
24+    source_stem: "bindgen",
25+    header_libs: ["libbpf_build_headers"],
26+    shared_libs: ["libbpf"],
27+}
28diff --git b/android/build.rs a/android/build.rs
29new file mode 100644
30index 0000000..7e4c2ee
31--- /dev/null
32+++ a/android/build.rs
33@@ -0,0 +1,58 @@
34+//! libbpf bindgen configuration
35+// Modified from the upstream libbpf-sys build.rs file in the libbpf-sys root dir.
36+use std::collections::HashSet;
37+fn main() {
38+    #[derive(Debug)]
39+    struct IgnoreMacros(HashSet<&'static str>);
40+    impl bindgen::callbacks::ParseCallbacks for IgnoreMacros {
41+        fn will_parse_macro(&self, name: &str) -> bindgen::callbacks::MacroParsingBehavior {
42+            if self.0.contains(name) {
43+                bindgen::callbacks::MacroParsingBehavior::Ignore
44+            } else {
45+                bindgen::callbacks::MacroParsingBehavior::Default
46+            }
47+        }
48+    }
49+    let ignored_macros = IgnoreMacros(
50+        vec![
51+            "BTF_KIND_FUNC",
52+            "BTF_KIND_FUNC_PROTO",
53+            "BTF_KIND_VAR",
54+            "BTF_KIND_DATASEC",
55+            "BTF_KIND_FLOAT",
56+            "BTF_KIND_DECL_TAG",
57+            "BTF_KIND_TYPE_TAG",
58+            "BTF_KIND_ENUM64",
59+        ]
60+        .into_iter()
61+        .collect(),
62+    );
63+    bindgen_cmd::build(|mut builder| {
64+        builder = builder
65+            .derive_default(true)
66+            .explicit_padding(true)
67+            .default_enum_style(bindgen::EnumVariation::Consts)
68+            .size_t_is_usize(false)
69+            .prepend_enum_name(false)
70+            .layout_tests(false)
71+            .generate_comments(false)
72+            .emit_builtins()
73+            .allowlist_function("bpf_.+")
74+            .allowlist_function("btf_.+")
75+            .allowlist_function("libbpf_.+")
76+            .allowlist_function("perf_.+")
77+            .allowlist_function("ring_buffer_.+")
78+            .allowlist_function("user_ring_buffer_.+")
79+            .allowlist_function("vdprintf")
80+            .allowlist_type("bpf_.+")
81+            .allowlist_type("btf_.+")
82+            .allowlist_type("xdp_.+")
83+            .allowlist_type("perf_.+")
84+            .allowlist_var("BPF_.+")
85+            .allowlist_var("BTF_.+")
86+            .allowlist_var("XDP_.+")
87+            .allowlist_var("PERF_.+")
88+            .parse_callbacks(Box::new(ignored_macros));
89+        builder
90+    })
91+}
92diff --git b/android/libbpf_wrapper.h a/android/libbpf_wrapper.h
93new file mode 100644
94index 0000000..b64ccef
95--- /dev/null
96+++ a/android/libbpf_wrapper.h
97@@ -0,0 +1,18 @@
98+/*
99+ * Copyright (C) 2024 The Android Open Source Project
100+ *
101+ * Licensed under the Apache License, Version 2.0 (the "License");
102+ * you may not use this file except in compliance with the License.
103+ * You may obtain a copy of the License at
104+ *
105+ *      http://www.apache.org/licenses/LICENSE-2.0
106+ *
107+ * Unless required by applicable law or agreed to in writing, software
108+ * distributed under the License is distributed on an "AS IS" BASIS,
109+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
110+ * See the License for the specific language governing permissions and
111+ * limitations under the License.
112+ */
113+#include "bpf/bpf.h"
114+#include "bpf/btf.h"
115+#include "bpf/libbpf.h"
116