diff --git a/cmake/OpenCensusHelpers.cmake b/cmake/OpenCensusHelpers.cmake
index 8fdfe96..53bc877 100644
--- a/cmake/OpenCensusHelpers.cmake
+++ b/cmake/OpenCensusHelpers.cmake
@@ -37,6 +37,13 @@ function(opencensus_test NAME SRC)
     prepend_opencensus(DEPS "${ARGN}")
     target_link_libraries(${_NAME} "${DEPS}" gmock gtest_main)
     add_test(NAME ${_NAME} COMMAND ${_NAME})
+
+    install(
+      TARGETS ${_NAME}
+      RUNTIME DESTINATION tools
+      LIBRARY DESTINATION lib
+      ARCHIVE DESTINATION lib
+    )
   endif()
 endfunction()
 
@@ -50,6 +57,13 @@ function(opencensus_benchmark NAME SRC)
     add_executable(${_NAME} ${SRC})
     prepend_opencensus(DEPS "${ARGN}")
     target_link_libraries(${_NAME} "${DEPS}" benchmark)
+
+    install(
+      TARGETS ${_NAME}
+      RUNTIME DESTINATION tools
+      LIBRARY DESTINATION lib
+      ARCHIVE DESTINATION lib
+    )
   endif()
 endfunction()
 
@@ -71,6 +85,12 @@ function(opencensus_lib NAME)
   if(ARG_PUBLIC)
     add_library(${PROJECT_NAME}::${NAME} ALIAS ${_NAME})
   endif()
+  install(
+    TARGETS ${_NAME}
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib
+  )
 endfunction()
 
 # Helper function for fuzzing. Usage:
@@ -83,5 +103,12 @@ function(opencensus_fuzzer NAME SRC)
     prepend_opencensus(DEPS "${ARGN}")
     target_link_libraries(${_NAME} "${DEPS}" ${FUZZER})
     target_compile_options(${_NAME} PRIVATE ${FUZZER})
+
+    install(
+      TARGETS ${_NAME}
+      RUNTIME DESTINATION tools
+      LIBRARY DESTINATION lib
+      ARCHIVE DESTINATION lib
+    )
   endif()
 endfunction()
diff --git a/examples/helloworld/CMakeLists.txt b/examples/helloworld/CMakeLists.txt
index 86cc1f4..cbbcb29 100644
--- a/examples/helloworld/CMakeLists.txt
+++ b/examples/helloworld/CMakeLists.txt
@@ -23,3 +23,10 @@ target_link_libraries(
   opencensus-cpp::stats
   opencensus-cpp::trace
   Threads::Threads)
+
+install(
+  TARGETS opencensus_examples_helloworld
+  RUNTIME DESTINATION tools
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib
+)
diff --git a/opencensus/common/internal/CMakeLists.txt b/opencensus/common/internal/CMakeLists.txt
index a9dbd87..810a8c8 100644
--- a/opencensus/common/internal/CMakeLists.txt
+++ b/opencensus/common/internal/CMakeLists.txt
@@ -23,6 +23,12 @@ opencensus_lib(
   absl::synchronization
   absl::time)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/common/internal)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/grpc/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/common/internal/grpc)
+
 opencensus_lib(common_stats_object DEPS absl::time)
 
 # Define NOMINMAX to fix build errors when compiling with MSVC.
diff --git a/opencensus/context/CMakeLists.txt b/opencensus/context/CMakeLists.txt
index 149958c..2474a66 100644
--- a/opencensus/context/CMakeLists.txt
+++ b/opencensus/context/CMakeLists.txt
@@ -22,6 +22,9 @@ opencensus_lib(
   tags
   trace)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/context)
+
 opencensus_test(
   context_context_test
   internal/context_test.cc
diff --git a/opencensus/exporters/stats/prometheus/CMakeLists.txt b/opencensus/exporters/stats/prometheus/CMakeLists.txt
index 01038cc..0ad712b 100644
--- a/opencensus/exporters/stats/prometheus/CMakeLists.txt
+++ b/opencensus/exporters/stats/prometheus/CMakeLists.txt
@@ -21,6 +21,12 @@ opencensus_lib(
   exporters_stats_prometheus_utils
   stats)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/exporters/stats/prometheus)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/internal/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/exporters/stats/prometheus/internal)
+
 opencensus_lib(
   exporters_stats_prometheus_utils
   SRCS
diff --git a/opencensus/exporters/stats/stdout/CMakeLists.txt b/opencensus/exporters/stats/stdout/CMakeLists.txt
index 5278e65..2930817 100644
--- a/opencensus/exporters/stats/stdout/CMakeLists.txt
+++ b/opencensus/exporters/stats/stdout/CMakeLists.txt
@@ -23,5 +23,8 @@ opencensus_lib(
   absl::strings
   absl::time)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/exporters/stats/stdout)
+
 opencensus_test(exporters_stats_stdout_test internal/stdout_exporter_test.cc
                 exporters_stats_stdout stats stats_test_utils absl::time)
diff --git a/opencensus/exporters/trace/stdout/CMakeLists.txt b/opencensus/exporters/trace/stdout/CMakeLists.txt
index c7c580f..d9befa1 100644
--- a/opencensus/exporters/trace/stdout/CMakeLists.txt
+++ b/opencensus/exporters/trace/stdout/CMakeLists.txt
@@ -22,5 +22,8 @@ opencensus_lib(
   absl::base
   absl::memory)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/exporters/trace/stdout)
+
 opencensus_test(exporters_trace_stdout_test internal/stdout_exporter_test.cc
                 exporters_trace_stdout trace absl::time)
diff --git a/opencensus/stats/CMakeLists.txt b/opencensus/stats/CMakeLists.txt
index 9b0d7af..a8a9d50 100644
--- a/opencensus/stats/CMakeLists.txt
+++ b/opencensus/stats/CMakeLists.txt
@@ -71,6 +71,12 @@ opencensus_lib(
   absl::strings
   absl::time)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/stats)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/internal/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/stats/internal)
+
 # ----------------------------------------------------------------------
 # Tests
 # ----------------------------------------------------------------------
diff --git a/opencensus/tags/CMakeLists.txt b/opencensus/tags/CMakeLists.txt
index 7219a2a..97a0de1 100644
--- a/opencensus/tags/CMakeLists.txt
+++ b/opencensus/tags/CMakeLists.txt
@@ -53,6 +53,12 @@ opencensus_lib(
   context
   absl::strings)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/tags)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/propagation/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/tags/propagation)
+
 opencensus_test(tags_context_util_test internal/context_util_test.cc tags
                 tags_context_util tags_with_tag_map context)
 
diff --git a/opencensus/trace/CMakeLists.txt b/opencensus/trace/CMakeLists.txt
index 2c4e656..25d7241 100644
--- a/opencensus/trace/CMakeLists.txt
+++ b/opencensus/trace/CMakeLists.txt
@@ -122,6 +122,18 @@ opencensus_lib(
   trace
   context)
 
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/trace)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/exporter/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/trace/exporter)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/internal/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/trace/internal)
+
+file(GLOB HDRS ${CMAKE_CURRENT_LIST_DIR}/propagation/*.h)
+install(FILES ${HDRS} DESTINATION include/opencensus-cpp/opencensus/trace/propagation)
+
 # ----------------------------------------------------------------------
 # Tests
 # ----------------------------------------------------------------------