diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ec669e..f71a212 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -81,6 +81,9 @@ set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package")
 set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library")
 set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package")
 
+set(gRPC_UPB_PROVIDER "module" CACHE STRING "Provider of upb library")
+set_property(CACHE gRPC_UPB_PROVIDER PROPERTY STRINGS "module" "package")
+
 set(gRPC_PROTOBUF_PACKAGE_TYPE "" CACHE STRING "Algorithm for searching protobuf package")
 set_property(CACHE gRPC_PROTOBUF_PACKAGE_TYPE PROPERTY STRINGS "CONFIG" "MODULE")
 
@@ -1765,7 +1768,6 @@ target_link_libraries(grpc
   ${_gRPC_ALLTARGETS_LIBRARIES}
   gpr
   address_sorting
-  upb
   absl::optional
   absl::strings
   absl::inlined_vector
@@ -1844,7 +1846,6 @@ target_link_libraries(grpc_csharp_ext
   grpc
   gpr
   address_sorting
-  upb
 )
 
 
@@ -2351,7 +2352,6 @@ target_link_libraries(grpc_unsecure
   ${_gRPC_ALLTARGETS_LIBRARIES}
   gpr
   address_sorting
-  upb
   absl::optional
   absl::strings
   absl::inlined_vector
@@ -2545,7 +2545,6 @@ target_link_libraries(grpc++
   grpc
   gpr
   address_sorting
-  upb
 )
 
 foreach(_hdr
@@ -2821,7 +2820,6 @@ target_link_libraries(grpc++_alts
   grpc
   gpr
   address_sorting
-  upb
 )
 
 foreach(_hdr
@@ -2889,7 +2887,6 @@ target_link_libraries(grpc++_error_details
   grpc
   gpr
   address_sorting
-  upb
 )
 
 foreach(_hdr
@@ -2962,7 +2959,6 @@ target_link_libraries(grpc++_reflection
   grpc
   gpr
   address_sorting
-  upb
 )
 
 foreach(_hdr
@@ -3239,7 +3235,6 @@ target_link_libraries(grpc++_unsecure
   grpc_unsecure
   gpr
   address_sorting
-  upb
 )
 
 foreach(_hdr
@@ -3586,7 +3581,6 @@ target_link_libraries(grpcpp_channelz
   grpc
   gpr
   address_sorting
-  upb
 )
 
 foreach(_hdr
@@ -3613,6 +3607,7 @@ endif()
 
 endif()
 
+if (gRPC_UPB_PROVIDER STREQUAL "module")
 add_library(upb
   third_party/upb/upb/decode.c
   third_party/upb/upb/encode.c
@@ -3662,7 +3657,7 @@ if(gRPC_INSTALL)
     ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
   )
 endif()
-
+endif()
 
 
 add_executable(check_epollexclusive
diff --git a/cmake/gRPCConfig.cmake.in b/cmake/gRPCConfig.cmake.in
index 5bfa73c..db0865e 100644
--- a/cmake/gRPCConfig.cmake.in
+++ b/cmake/gRPCConfig.cmake.in
@@ -7,6 +7,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/modules)
 @_gRPC_FIND_SSL@
 @_gRPC_FIND_CARES@
 @_gRPC_FIND_ABSL@
+@_gRPC_FIND_UPB@
 
 # Targets
 include(${CMAKE_CURRENT_LIST_DIR}/gRPCTargets.cmake)
diff --git a/cmake/upb.cmake b/cmake/upb.cmake
index 2c0ab84..07dd613 100644
--- a/cmake/upb.cmake
+++ b/cmake/upb.cmake
@@ -12,9 +12,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-generated")
+if (gRPC_UPB_PROVIDER STREQUAL "module")
 set(UPB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/upb)
 
 set(_gRPC_UPB_INCLUDE_DIR "${UPB_ROOT_DIR}")
-set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-generated")
 
 set(_gRPC_UPB_LIBRARIES upb)
+
+elseif(gRPC_UPB_PROVIDER STREQUAL "package")
+    find_package(upb CONFIG REQUIRED)
+    set(_gRPC_UPB_LIBRARIES upb::upb)
+    set(_gRPC_UPB_INCLUDE_DIR)
+    set(upb ${_gRPC_UPB_LIBRARIES})
+    set(_gRPC_FIND_UPB "if(NOT upb_FOUND)\n  find_package(upb CONFIG REQUIRED)\nendif()")
+endif()
