diff --git a/.gitmodules b/.gitmodules
index 008bc5fae809b9327614df4a432c2d3d894f2c61..c37d0abdf0bdf70f9b97f16bf7ae6010d16c6eb5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -14,3 +14,6 @@
 [submodule "third_party/boringssl"]
 	path = third_party/boringssl
 	url = https://boringssl.googlesource.com/boringssl
+[submodule "third_party/nanopb"]
+	path = third_party/nanopb
+	url = https://github.com/nanopb/nanopb.git
diff --git a/BUILD b/BUILD
index 72d5caa8d43142350763da7e60603bd5c6db29ad..31e0f3aacc68bccee0a9ca940b9a13a84f93d99c 100644
--- a/BUILD
+++ b/BUILD
@@ -182,6 +182,7 @@ cc_library(
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -242,6 +243,7 @@ cc_library(
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -283,6 +285,10 @@ cc_library(
     "src/core/transport/transport_impl.h",
     "src/core/census/aggregation.h",
     "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
     "src/core/httpcli/httpcli_security_connector.c",
     "src/core/security/base64.c",
     "src/core/security/client_auth_filter.c",
@@ -319,6 +325,7 @@ cc_library(
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -382,6 +389,7 @@ cc_library(
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -436,6 +444,9 @@ cc_library(
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
@@ -484,6 +495,7 @@ cc_library(
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -544,6 +556,7 @@ cc_library(
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -585,6 +598,10 @@ cc_library(
     "src/core/transport/transport_impl.h",
     "src/core/census/aggregation.h",
     "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
     "src/core/surface/init_unsecure.c",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
@@ -601,6 +618,7 @@ cc_library(
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -664,6 +682,7 @@ cc_library(
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -718,6 +737,9 @@ cc_library(
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
   ],
   hdrs = [
     "include/grpc/byte_buffer.h",
@@ -1281,6 +1303,7 @@ objc_library(
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -1344,6 +1367,7 @@ objc_library(
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -1398,6 +1422,9 @@ objc_library(
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
@@ -1441,6 +1468,7 @@ objc_library(
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -1501,6 +1529,7 @@ objc_library(
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -1542,6 +1571,10 @@ objc_library(
     "src/core/transport/transport_impl.h",
     "src/core/census/aggregation.h",
     "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
   ],
   includes = [
     "include",
diff --git a/Makefile b/Makefile
index 3c215b35b6438c9644022a24958af6cb4752887c..01bbb2cb3c4fd87b9c195a4a4fbc7c737cd68f53 100644
--- a/Makefile
+++ b/Makefile
@@ -940,6 +940,7 @@ grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin
 grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
 grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
 grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
 hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
 interop_server: $(BINDIR)/$(CONFIG)/interop_server
@@ -1283,6 +1284,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test \
   $(BINDIR)/$(CONFIG)/generic_end2end_test \
   $(BINDIR)/$(CONFIG)/grpc_cli \
+  $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
   $(BINDIR)/$(CONFIG)/interop_client \
   $(BINDIR)/$(CONFIG)/interop_server \
@@ -1591,6 +1593,8 @@ test_cxx: test_zookeeper buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test || ( echo test generic_async_streaming_ping_pong_test failed ; exit 1 )
 	$(E) "[RUN]     Testing generic_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
+	$(E) "[RUN]     Testing grpclb_api_test"
+	$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
 	$(E) "[RUN]     Testing hybrid_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing interop_test"
@@ -1740,6 +1744,21 @@ $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc:
 	$(Q) mkdir -p $(@D)
 	$(Q) echo "$(GRPCXX_UNSECURE_PC_FILE)" | tr , '\n' >$@
 
+ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc: protoc_dep_error
+else
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc: src/proto/grpc/lb/v0/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v0/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+endif
+
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/control.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: protoc_dep_error
@@ -2348,6 +2367,7 @@ LIBGRPC_SRC = \
     src/core/client_config/connector.c \
     src/core/client_config/default_initial_connect_string.c \
     src/core/client_config/initial_connect_string.c \
+    src/core/client_config/lb_policies/load_balancer_api.c \
     src/core/client_config/lb_policies/pick_first.c \
     src/core/client_config/lb_policies/round_robin.c \
     src/core/client_config/lb_policy.c \
@@ -2411,6 +2431,7 @@ LIBGRPC_SRC = \
     src/core/json/json_reader.c \
     src/core/json/json_string.c \
     src/core/json/json_writer.c \
+    src/core/proto/grpc/lb/v0/load_balancer.pb.c \
     src/core/surface/alarm.c \
     src/core/surface/api_trace.c \
     src/core/surface/byte_buffer.c \
@@ -2465,6 +2486,9 @@ LIBGRPC_SRC = \
     src/core/census/operation.c \
     src/core/census/placeholders.c \
     src/core/census/tracing.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
 
 PUBLIC_HEADERS_C += \
     include/grpc/grpc_security.h \
@@ -2632,6 +2656,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/client_config/connector.c \
     src/core/client_config/default_initial_connect_string.c \
     src/core/client_config/initial_connect_string.c \
+    src/core/client_config/lb_policies/load_balancer_api.c \
     src/core/client_config/lb_policies/pick_first.c \
     src/core/client_config/lb_policies/round_robin.c \
     src/core/client_config/lb_policy.c \
@@ -2695,6 +2720,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/json/json_reader.c \
     src/core/json/json_string.c \
     src/core/json/json_writer.c \
+    src/core/proto/grpc/lb/v0/load_balancer.pb.c \
     src/core/surface/alarm.c \
     src/core/surface/api_trace.c \
     src/core/surface/byte_buffer.c \
@@ -2749,6 +2775,9 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/census/operation.c \
     src/core/census/placeholders.c \
     src/core/census/tracing.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
 
 PUBLIC_HEADERS_C += \
     include/grpc/byte_buffer.h \
@@ -9670,6 +9699,53 @@ ifneq ($(NO_DEPS),true)
 endif
 
 
+GRPCLB_API_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc \
+    test/cpp/grpclb/grpclb_api_test.cc \
+
+GRPCLB_API_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_API_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/grpclb_api_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpclb_api_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpclb_api_test: $(PROTOBUF_DEP) $(GRPCLB_API_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_API_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_api_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v0/load_balancer.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
+
+deps_grpclb_api_test: $(GRPCLB_API_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPCLB_API_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o: $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc
+
+
 HYBRID_END2END_TEST_SRC = \
     test/cpp/end2end/hybrid_end2end_test.cc \
 
diff --git a/binding.gyp b/binding.gyp
index 3659bfcf13e0f604d609d33313908d86b054d579..f7a21e56cd2ec9f1bb5610d3dd0c3706d102dfd2 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -591,6 +591,7 @@
         'src/core/client_config/connector.c',
         'src/core/client_config/default_initial_connect_string.c',
         'src/core/client_config/initial_connect_string.c',
+        'src/core/client_config/lb_policies/load_balancer_api.c',
         'src/core/client_config/lb_policies/pick_first.c',
         'src/core/client_config/lb_policies/round_robin.c',
         'src/core/client_config/lb_policy.c',
@@ -654,6 +655,7 @@
         'src/core/json/json_reader.c',
         'src/core/json/json_string.c',
         'src/core/json/json_writer.c',
+        'src/core/proto/grpc/lb/v0/load_balancer.pb.c',
         'src/core/surface/alarm.c',
         'src/core/surface/api_trace.c',
         'src/core/surface/byte_buffer.c',
@@ -708,6 +710,9 @@
         'src/core/census/operation.c',
         'src/core/census/placeholders.c',
         'src/core/census/tracing.c',
+        'third_party/nanopb/pb_common.c',
+        'third_party/nanopb/pb_decode.c',
+        'third_party/nanopb/pb_encode.c',
       ],
       "conditions": [
         ['OS == "mac"', {
diff --git a/build.yaml b/build.yaml
index 7f33ef3f0e580f09d43b47b4fb6fc4bb5a977325..ffa16675d82fb12a95eaa075bbc8c53e85c1d51d 100644
--- a/build.yaml
+++ b/build.yaml
@@ -258,6 +258,7 @@ filegroups:
   - src/core/client_config/client_config.h
   - src/core/client_config/connector.h
   - src/core/client_config/initial_connect_string.h
+  - src/core/client_config/lb_policies/load_balancer_api.h
   - src/core/client_config/lb_policies/pick_first.h
   - src/core/client_config/lb_policies/round_robin.h
   - src/core/client_config/lb_policy.h
@@ -318,6 +319,7 @@ filegroups:
   - src/core/json/json_common.h
   - src/core/json/json_reader.h
   - src/core/json/json_writer.h
+  - src/core/proto/grpc/lb/v0/load_balancer.pb.h
   - src/core/statistics/census_interface.h
   - src/core/statistics/census_rpc_stats.h
   - src/core/surface/api_trace.h
@@ -373,6 +375,7 @@ filegroups:
   - src/core/client_config/connector.c
   - src/core/client_config/default_initial_connect_string.c
   - src/core/client_config/initial_connect_string.c
+  - src/core/client_config/lb_policies/load_balancer_api.c
   - src/core/client_config/lb_policies/pick_first.c
   - src/core/client_config/lb_policies/round_robin.c
   - src/core/client_config/lb_policy.c
@@ -436,6 +439,7 @@ filegroups:
   - src/core/json/json_reader.c
   - src/core/json/json_string.c
   - src/core/json/json_writer.c
+  - src/core/proto/grpc/lb/v0/load_balancer.pb.c
   - src/core/surface/alarm.c
   - src/core/surface/api_trace.c
   - src/core/surface/byte_buffer.c
@@ -511,6 +515,16 @@ filegroups:
   - test/core/util/port_posix.c
   - test/core/util/port_windows.c
   - test/core/util/slice_splitter.c
+- name: nanopb
+  headers:
+  - third_party/nanopb/pb.h
+  - third_party/nanopb/pb_common.h
+  - third_party/nanopb/pb_decode.h
+  - third_party/nanopb/pb_encode.h
+  src:
+  - third_party/nanopb/pb_common.c
+  - third_party/nanopb/pb_decode.c
+  - third_party/nanopb/pb_encode.c
 libs:
 - name: gpr
   build: all
@@ -582,6 +596,7 @@ libs:
   - grpc_codegen
   - grpc_base
   - census
+  - nanopb
   secure: true
   vs_packages:
   - grpc.dependencies.openssl
@@ -630,6 +645,7 @@ libs:
   - grpc_base
   - grpc_codegen
   - census
+  - nanopb
   secure: false
   vs_project_guid: '{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}'
 - name: grpc_zookeeper
@@ -2174,6 +2190,17 @@ targets:
   secure: false
   vs_config_type: Application
   vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}'
+- name: grpclb_api_test
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/lb/v0/load_balancer.proto
+  - test/cpp/grpclb/grpclb_api_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
 - name: hybrid_end2end_test
   build: test
   language: c++
diff --git a/gRPC.podspec b/gRPC.podspec
index 5b4d24e4820d6e59a42d34c7529d8c29974f63f8..05e3802b77ffe6646e3cf8a5d37b73a70377f1a8 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -186,6 +186,7 @@ Pod::Spec.new do |s|
                       'src/core/client_config/client_config.h',
                       'src/core/client_config/connector.h',
                       'src/core/client_config/initial_connect_string.h',
+                      'src/core/client_config/lb_policies/load_balancer_api.h',
                       'src/core/client_config/lb_policies/pick_first.h',
                       'src/core/client_config/lb_policies/round_robin.h',
                       'src/core/client_config/lb_policy.h',
@@ -246,6 +247,7 @@ Pod::Spec.new do |s|
                       'src/core/json/json_common.h',
                       'src/core/json/json_reader.h',
                       'src/core/json/json_writer.h',
+                      'src/core/proto/grpc/lb/v0/load_balancer.pb.h',
                       'src/core/statistics/census_interface.h',
                       'src/core/statistics/census_rpc_stats.h',
                       'src/core/surface/api_trace.h',
@@ -287,6 +289,10 @@ Pod::Spec.new do |s|
                       'src/core/transport/transport_impl.h',
                       'src/core/census/aggregation.h',
                       'src/core/census/rpc_metric_id.h',
+                      'third_party/nanopb/pb.h',
+                      'third_party/nanopb/pb_common.h',
+                      'third_party/nanopb/pb_decode.h',
+                      'third_party/nanopb/pb_encode.h',
                       'include/grpc/grpc_security.h',
                       'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/compression_types.h',
@@ -336,6 +342,7 @@ Pod::Spec.new do |s|
                       'src/core/client_config/connector.c',
                       'src/core/client_config/default_initial_connect_string.c',
                       'src/core/client_config/initial_connect_string.c',
+                      'src/core/client_config/lb_policies/load_balancer_api.c',
                       'src/core/client_config/lb_policies/pick_first.c',
                       'src/core/client_config/lb_policies/round_robin.c',
                       'src/core/client_config/lb_policy.c',
@@ -399,6 +406,7 @@ Pod::Spec.new do |s|
                       'src/core/json/json_reader.c',
                       'src/core/json/json_string.c',
                       'src/core/json/json_writer.c',
+                      'src/core/proto/grpc/lb/v0/load_balancer.pb.c',
                       'src/core/surface/alarm.c',
                       'src/core/surface/api_trace.c',
                       'src/core/surface/byte_buffer.c',
@@ -452,7 +460,10 @@ Pod::Spec.new do |s|
                       'src/core/census/initialize.c',
                       'src/core/census/operation.c',
                       'src/core/census/placeholders.c',
-                      'src/core/census/tracing.c'
+                      'src/core/census/tracing.c',
+                      'third_party/nanopb/pb_common.c',
+                      'third_party/nanopb/pb_decode.c',
+                      'third_party/nanopb/pb_encode.c'
 
     ss.private_header_files = 'src/core/profiling/timers.h',
                               'src/core/support/block_annotate.h',
@@ -492,6 +503,7 @@ Pod::Spec.new do |s|
                               'src/core/client_config/client_config.h',
                               'src/core/client_config/connector.h',
                               'src/core/client_config/initial_connect_string.h',
+                              'src/core/client_config/lb_policies/load_balancer_api.h',
                               'src/core/client_config/lb_policies/pick_first.h',
                               'src/core/client_config/lb_policies/round_robin.h',
                               'src/core/client_config/lb_policy.h',
@@ -552,6 +564,7 @@ Pod::Spec.new do |s|
                               'src/core/json/json_common.h',
                               'src/core/json/json_reader.h',
                               'src/core/json/json_writer.h',
+                              'src/core/proto/grpc/lb/v0/load_balancer.pb.h',
                               'src/core/statistics/census_interface.h',
                               'src/core/statistics/census_rpc_stats.h',
                               'src/core/surface/api_trace.h',
@@ -592,7 +605,11 @@ Pod::Spec.new do |s|
                               'src/core/transport/transport.h',
                               'src/core/transport/transport_impl.h',
                               'src/core/census/aggregation.h',
-                              'src/core/census/rpc_metric_id.h'
+                              'src/core/census/rpc_metric_id.h',
+                              'third_party/nanopb/pb.h',
+                              'third_party/nanopb/pb_common.h',
+                              'third_party/nanopb/pb_decode.h',
+                              'third_party/nanopb/pb_encode.h'
 
     ss.header_mappings_dir = '.'
     # This isn't officially supported in Cocoapods. We've asked for an alternative:
diff --git a/grpc.gemspec b/grpc.gemspec
index 9e4683f41c794cb5de605f779cf7ea9597c07ba5..1ef26761b72c8efd810eb71f8520144916bbe528 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -182,6 +182,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/client_config/client_config.h )
   s.files += %w( src/core/client_config/connector.h )
   s.files += %w( src/core/client_config/initial_connect_string.h )
+  s.files += %w( src/core/client_config/lb_policies/load_balancer_api.h )
   s.files += %w( src/core/client_config/lb_policies/pick_first.h )
   s.files += %w( src/core/client_config/lb_policies/round_robin.h )
   s.files += %w( src/core/client_config/lb_policy.h )
@@ -242,6 +243,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/json/json_common.h )
   s.files += %w( src/core/json/json_reader.h )
   s.files += %w( src/core/json/json_writer.h )
+  s.files += %w( src/core/proto/grpc/lb/v0/load_balancer.pb.h )
   s.files += %w( src/core/statistics/census_interface.h )
   s.files += %w( src/core/statistics/census_rpc_stats.h )
   s.files += %w( src/core/surface/api_trace.h )
@@ -283,6 +285,10 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/transport/transport_impl.h )
   s.files += %w( src/core/census/aggregation.h )
   s.files += %w( src/core/census/rpc_metric_id.h )
+  s.files += %w( third_party/nanopb/pb.h )
+  s.files += %w( third_party/nanopb/pb_common.h )
+  s.files += %w( third_party/nanopb/pb_decode.h )
+  s.files += %w( third_party/nanopb/pb_encode.h )
   s.files += %w( src/core/httpcli/httpcli_security_connector.c )
   s.files += %w( src/core/security/base64.c )
   s.files += %w( src/core/security/client_auth_filter.c )
@@ -319,6 +325,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/client_config/connector.c )
   s.files += %w( src/core/client_config/default_initial_connect_string.c )
   s.files += %w( src/core/client_config/initial_connect_string.c )
+  s.files += %w( src/core/client_config/lb_policies/load_balancer_api.c )
   s.files += %w( src/core/client_config/lb_policies/pick_first.c )
   s.files += %w( src/core/client_config/lb_policies/round_robin.c )
   s.files += %w( src/core/client_config/lb_policy.c )
@@ -382,6 +389,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/json/json_reader.c )
   s.files += %w( src/core/json/json_string.c )
   s.files += %w( src/core/json/json_writer.c )
+  s.files += %w( src/core/proto/grpc/lb/v0/load_balancer.pb.c )
   s.files += %w( src/core/surface/alarm.c )
   s.files += %w( src/core/surface/api_trace.c )
   s.files += %w( src/core/surface/byte_buffer.c )
@@ -436,6 +444,9 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/census/operation.c )
   s.files += %w( src/core/census/placeholders.c )
   s.files += %w( src/core/census/tracing.c )
+  s.files += %w( third_party/nanopb/pb_common.c )
+  s.files += %w( third_party/nanopb/pb_decode.c )
+  s.files += %w( third_party/nanopb/pb_encode.c )
   s.files += %w( third_party/boringssl/crypto/aes/internal.h )
   s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )
   s.files += %w( third_party/boringssl/crypto/bio/internal.h )
diff --git a/package.json b/package.json
index 1b79ecf92dc9f07d91bb23d86ef4ec8250fccf7e..b8f8c0a256e4bfb9664cbbfbc713f4eb821ab41f 100644
--- a/package.json
+++ b/package.json
@@ -128,6 +128,7 @@
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -188,6 +189,7 @@
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -229,6 +231,10 @@
     "src/core/transport/transport_impl.h",
     "src/core/census/aggregation.h",
     "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
     "src/core/httpcli/httpcli_security_connector.c",
     "src/core/security/base64.c",
     "src/core/security/client_auth_filter.c",
@@ -265,6 +271,7 @@
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -328,6 +335,7 @@
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -382,6 +390,9 @@
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
     "third_party/zlib/crc32.h",
     "third_party/zlib/deflate.h",
     "third_party/zlib/gzguts.h",
diff --git a/src/core/client_config/lb_policies/load_balancer_api.c b/src/core/client_config/lb_policies/load_balancer_api.c
new file mode 100644
index 0000000000000000000000000000000000000000..a6b5785fe4ed088eeacb0d19154facdf809760ba
--- /dev/null
+++ b/src/core/client_config/lb_policies/load_balancer_api.c
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/client_config/lb_policies/load_balancer_api.h"
+#include "third_party/nanopb/pb_decode.h"
+#include "third_party/nanopb/pb_encode.h"
+
+#include <grpc/support/alloc.h>
+
+typedef struct decode_serverlist_arg {
+  int first_pass;
+  int i;
+  size_t num_servers;
+  grpc_grpclb_server **servers;
+} decode_serverlist_arg;
+
+/* invoked once for every Server in ServerList */
+static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
+                              void **arg) {
+  decode_serverlist_arg *dec_arg = *arg;
+  if (dec_arg->first_pass != 0) { /* first pass */
+    grpc_grpclb_server server;
+    if (!pb_decode(stream, grpc_lb_v0_Server_fields, &server)) {
+      return false;
+    }
+    dec_arg->num_servers++;
+  } else { /* second pass */
+    grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server));
+    GPR_ASSERT(dec_arg->num_servers > 0);
+    if (dec_arg->i == 0) { /* first iteration of second pass */
+      dec_arg->servers =
+          gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers);
+    }
+    if (!pb_decode(stream, grpc_lb_v0_Server_fields, server)) {
+      return false;
+    }
+    dec_arg->servers[dec_arg->i++] = server;
+  }
+
+  return true;
+}
+
+grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) {
+  grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request));
+
+  req->has_client_stats = 0; /* TODO(dgq): add support for stats once defined */
+  req->has_initial_request = 1;
+  req->initial_request.has_name = 1;
+  strncpy(req->initial_request.name, lb_service_name,
+          GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
+  return req;
+}
+
+gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
+  size_t encoded_length;
+  pb_ostream_t sizestream;
+  pb_ostream_t outputstream;
+  gpr_slice slice;
+  memset(&sizestream, 0, sizeof(pb_ostream_t));
+  pb_encode(&sizestream, grpc_lb_v0_LoadBalanceRequest_fields, request);
+  encoded_length = sizestream.bytes_written;
+
+  slice = gpr_slice_malloc(encoded_length);
+  outputstream =
+      pb_ostream_from_buffer(GPR_SLICE_START_PTR(slice), encoded_length);
+  GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v0_LoadBalanceRequest_fields,
+                       request) != 0);
+  return slice;
+}
+
+void grpc_grpclb_request_destroy(grpc_grpclb_request *request) {
+  gpr_free(request);
+}
+
+grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) {
+  bool status;
+  pb_istream_t stream =
+      pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
+                             GPR_SLICE_LENGTH(encoded_response));
+  grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
+  memset(res, 0, sizeof(*res));
+  status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
+  GPR_ASSERT(status == true);
+  return res;
+}
+
+grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
+    gpr_slice encoded_response) {
+  grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist));
+  bool status;
+  decode_serverlist_arg arg;
+  pb_istream_t stream =
+      pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
+                             GPR_SLICE_LENGTH(encoded_response));
+  pb_istream_t stream_at_start = stream;
+  grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
+  memset(res, 0, sizeof(*res));
+  memset(&arg, 0, sizeof(decode_serverlist_arg));
+
+  res->server_list.servers.funcs.decode = decode_serverlist;
+  res->server_list.servers.arg = &arg;
+  arg.first_pass = 1;
+  status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
+  GPR_ASSERT(status == true);
+  GPR_ASSERT(arg.num_servers > 0);
+
+  arg.first_pass = 0;
+  status =
+      pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res);
+  GPR_ASSERT(status == true);
+  GPR_ASSERT(arg.servers != NULL);
+
+  sl->num_servers = arg.num_servers;
+  sl->servers = arg.servers;
+  if (res->server_list.has_expiration_interval) {
+    sl->expiration_interval = res->server_list.expiration_interval;
+  }
+  grpc_grpclb_response_destroy(res);
+  return sl;
+}
+
+void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) {
+  size_t i;
+  for (i = 0; i < serverlist->num_servers; i++) {
+    gpr_free(serverlist->servers[i]);
+  }
+  gpr_free(serverlist->servers);
+  gpr_free(serverlist);
+}
+
+void grpc_grpclb_response_destroy(grpc_grpclb_response *response) {
+  gpr_free(response);
+}
diff --git a/src/core/client_config/lb_policies/load_balancer_api.h b/src/core/client_config/lb_policies/load_balancer_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..4dbe1d6c224ef595fe82cf3812c25f0293ae78c9
--- /dev/null
+++ b/src/core/client_config/lb_policies/load_balancer_api.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
+#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
+
+#include <grpc/support/slice_buffer.h>
+
+#include "src/core/client_config/lb_policy_factory.h"
+#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
+
+typedef grpc_lb_v0_LoadBalanceRequest grpc_grpclb_request;
+typedef grpc_lb_v0_LoadBalanceResponse grpc_grpclb_response;
+typedef grpc_lb_v0_Server grpc_grpclb_server;
+typedef grpc_lb_v0_Duration grpc_grpclb_duration;
+typedef struct grpc_grpclb_serverlist {
+  grpc_grpclb_server **servers;
+  size_t num_servers;
+  grpc_grpclb_duration expiration_interval;
+} grpc_grpclb_serverlist;
+
+/** Create a request for a gRPC LB service under \a lb_service_name */
+grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name);
+
+/** Protocol Buffers v3-encode \a request */
+gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request);
+
+/** Destroy \a request */
+void grpc_grpclb_request_destroy(grpc_grpclb_request *request);
+
+/** Parse (ie, decode) the bytes in \a encoded_response as a \a
+ * grpc_grpclb_response */
+grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response);
+
+/** Destroy \a serverlist */
+void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist);
+
+/** Parse the list of servers from an encoded \a grpc_grpclb_response */
+grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
+    gpr_slice encoded_response);
+
+/** Destroy \a response */
+void grpc_grpclb_response_destroy(grpc_grpclb_response *response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */
diff --git a/src/core/proto/grpc/lb/v0/load_balancer.pb.c b/src/core/proto/grpc/lb/v0/load_balancer.pb.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbb6fa82249ffb617e446bbb31570fa69e6ece5f
--- /dev/null
+++ b/src/core/proto/grpc/lb/v0/load_balancer.pb.c
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.4-dev */
+
+#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h"
+
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+const pb_field_t grpc_lb_v0_Duration_fields[3] = {
+    PB_FIELD(1, INT64, OPTIONAL, STATIC, FIRST, grpc_lb_v0_Duration, seconds,
+             seconds, 0),
+    PB_FIELD(2, INT32, OPTIONAL, STATIC, OTHER, grpc_lb_v0_Duration, nanos,
+             seconds, 0),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3] = {
+    PB_FIELD(1, MESSAGE, OPTIONAL, STATIC, FIRST, grpc_lb_v0_LoadBalanceRequest,
+             initial_request, initial_request,
+             &grpc_lb_v0_InitialLoadBalanceRequest_fields),
+    PB_FIELD(2, MESSAGE, OPTIONAL, STATIC, OTHER, grpc_lb_v0_LoadBalanceRequest,
+             client_stats, initial_request, &grpc_lb_v0_ClientStats_fields),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2] = {
+    PB_FIELD(1, STRING, OPTIONAL, STATIC, FIRST,
+             grpc_lb_v0_InitialLoadBalanceRequest, name, name, 0),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_ClientStats_fields[4] = {
+    PB_FIELD(1, INT64, OPTIONAL, STATIC, FIRST, grpc_lb_v0_ClientStats,
+             total_requests, total_requests, 0),
+    PB_FIELD(2, INT64, OPTIONAL, STATIC, OTHER, grpc_lb_v0_ClientStats,
+             client_rpc_errors, total_requests, 0),
+    PB_FIELD(3, INT64, OPTIONAL, STATIC, OTHER, grpc_lb_v0_ClientStats,
+             dropped_requests, client_rpc_errors, 0),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3] = {
+    PB_FIELD(1, MESSAGE, OPTIONAL, STATIC, FIRST,
+             grpc_lb_v0_LoadBalanceResponse, initial_response, initial_response,
+             &grpc_lb_v0_InitialLoadBalanceResponse_fields),
+    PB_FIELD(2, MESSAGE, OPTIONAL, STATIC, OTHER,
+             grpc_lb_v0_LoadBalanceResponse, server_list, initial_response,
+             &grpc_lb_v0_ServerList_fields),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4] = {
+    PB_FIELD(1, STRING, OPTIONAL, STATIC, FIRST,
+             grpc_lb_v0_InitialLoadBalanceResponse, client_config,
+             client_config, 0),
+    PB_FIELD(2, STRING, OPTIONAL, STATIC, OTHER,
+             grpc_lb_v0_InitialLoadBalanceResponse, load_balancer_delegate,
+             client_config, 0),
+    PB_FIELD(3, MESSAGE, OPTIONAL, STATIC, OTHER,
+             grpc_lb_v0_InitialLoadBalanceResponse,
+             client_stats_report_interval, load_balancer_delegate,
+             &grpc_lb_v0_Duration_fields),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_ServerList_fields[3] = {
+    PB_FIELD(1, MESSAGE, REPEATED, CALLBACK, FIRST, grpc_lb_v0_ServerList,
+             servers, servers, &grpc_lb_v0_Server_fields),
+    PB_FIELD(3, MESSAGE, OPTIONAL, STATIC, OTHER, grpc_lb_v0_ServerList,
+             expiration_interval, servers, &grpc_lb_v0_Duration_fields),
+    PB_LAST_FIELD};
+
+const pb_field_t grpc_lb_v0_Server_fields[5] = {
+    PB_FIELD(1, STRING, OPTIONAL, STATIC, FIRST, grpc_lb_v0_Server, ip_address,
+             ip_address, 0),
+    PB_FIELD(2, INT32, OPTIONAL, STATIC, OTHER, grpc_lb_v0_Server, port,
+             ip_address, 0),
+    PB_FIELD(3, BYTES, OPTIONAL, STATIC, OTHER, grpc_lb_v0_Server,
+             load_balance_token, port, 0),
+    PB_FIELD(4, BOOL, OPTIONAL, STATIC, OTHER, grpc_lb_v0_Server, drop_request,
+             load_balance_token, 0),
+    PB_LAST_FIELD};
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT(
+    (pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 65536 &&
+     pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 65536 &&
+     pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 65536 &&
+     pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 65536 &&
+     pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse,
+                   client_stats_report_interval) < 65536 &&
+     pb_membersize(grpc_lb_v0_ServerList, servers) < 65536 &&
+     pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 65536),
+    YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT(
+    (pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 256 &&
+     pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 256 &&
+     pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 256 &&
+     pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 256 &&
+     pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse,
+                   client_stats_report_interval) < 256 &&
+     pb_membersize(grpc_lb_v0_ServerList, servers) < 256 &&
+     pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 256),
+    YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server)
+#endif
diff --git a/src/core/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/proto/grpc/lb/v0/load_balancer.pb.h
new file mode 100644
index 0000000000000000000000000000000000000000..ac836658399df62facd01667903ed2db7a2550c4
--- /dev/null
+++ b/src/core/proto/grpc/lb/v0/load_balancer.pb.h
@@ -0,0 +1,221 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.4-dev */
+
+#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED
+#define PB_LOAD_BALANCER_PB_H_INCLUDED
+#include "third_party/nanopb/pb.h"
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enum definitions */
+/* Struct definitions */
+typedef struct _grpc_lb_v0_ClientStats {
+  bool has_total_requests;
+  int64_t total_requests;
+  bool has_client_rpc_errors;
+  int64_t client_rpc_errors;
+  bool has_dropped_requests;
+  int64_t dropped_requests;
+} grpc_lb_v0_ClientStats;
+
+typedef struct _grpc_lb_v0_Duration {
+  bool has_seconds;
+  int64_t seconds;
+  bool has_nanos;
+  int32_t nanos;
+} grpc_lb_v0_Duration;
+
+typedef struct _grpc_lb_v0_InitialLoadBalanceRequest {
+  bool has_name;
+  char name[128];
+} grpc_lb_v0_InitialLoadBalanceRequest;
+
+typedef PB_BYTES_ARRAY_T(64) grpc_lb_v0_Server_load_balance_token_t;
+typedef struct _grpc_lb_v0_Server {
+  bool has_ip_address;
+  char ip_address[46];
+  bool has_port;
+  int32_t port;
+  bool has_load_balance_token;
+  grpc_lb_v0_Server_load_balance_token_t load_balance_token;
+  bool has_drop_request;
+  bool drop_request;
+} grpc_lb_v0_Server;
+
+typedef struct _grpc_lb_v0_InitialLoadBalanceResponse {
+  bool has_client_config;
+  char client_config[64];
+  bool has_load_balancer_delegate;
+  char load_balancer_delegate[64];
+  bool has_client_stats_report_interval;
+  grpc_lb_v0_Duration client_stats_report_interval;
+} grpc_lb_v0_InitialLoadBalanceResponse;
+
+typedef struct _grpc_lb_v0_LoadBalanceRequest {
+  bool has_initial_request;
+  grpc_lb_v0_InitialLoadBalanceRequest initial_request;
+  bool has_client_stats;
+  grpc_lb_v0_ClientStats client_stats;
+} grpc_lb_v0_LoadBalanceRequest;
+
+typedef struct _grpc_lb_v0_ServerList {
+  pb_callback_t servers;
+  bool has_expiration_interval;
+  grpc_lb_v0_Duration expiration_interval;
+} grpc_lb_v0_ServerList;
+
+typedef struct _grpc_lb_v0_LoadBalanceResponse {
+  bool has_initial_response;
+  grpc_lb_v0_InitialLoadBalanceResponse initial_response;
+  bool has_server_list;
+  grpc_lb_v0_ServerList server_list;
+} grpc_lb_v0_LoadBalanceResponse;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define grpc_lb_v0_Duration_init_default \
+  { false, 0, false, 0 }
+#define grpc_lb_v0_LoadBalanceRequest_init_default                   \
+  {                                                                  \
+    false, grpc_lb_v0_InitialLoadBalanceRequest_init_default, false, \
+        grpc_lb_v0_ClientStats_init_default                          \
+  }
+#define grpc_lb_v0_InitialLoadBalanceRequest_init_default \
+  { false, "" }
+#define grpc_lb_v0_ClientStats_init_default \
+  { false, 0, false, 0, false, 0 }
+#define grpc_lb_v0_LoadBalanceResponse_init_default                   \
+  {                                                                   \
+    false, grpc_lb_v0_InitialLoadBalanceResponse_init_default, false, \
+        grpc_lb_v0_ServerList_init_default                            \
+  }
+#define grpc_lb_v0_InitialLoadBalanceResponse_init_default \
+  { false, "", false, "", false, grpc_lb_v0_Duration_init_default }
+#define grpc_lb_v0_ServerList_init_default    \
+  {                                           \
+    {                                         \
+      { NULL }                                \
+      , NULL                                  \
+    }                                         \
+    , false, grpc_lb_v0_Duration_init_default \
+  }
+#define grpc_lb_v0_Server_init_default \
+  { false, "", false, 0, false, {0, {0}}, false, 0 }
+#define grpc_lb_v0_Duration_init_zero \
+  { false, 0, false, 0 }
+#define grpc_lb_v0_LoadBalanceRequest_init_zero                   \
+  {                                                               \
+    false, grpc_lb_v0_InitialLoadBalanceRequest_init_zero, false, \
+        grpc_lb_v0_ClientStats_init_zero                          \
+  }
+#define grpc_lb_v0_InitialLoadBalanceRequest_init_zero \
+  { false, "" }
+#define grpc_lb_v0_ClientStats_init_zero \
+  { false, 0, false, 0, false, 0 }
+#define grpc_lb_v0_LoadBalanceResponse_init_zero                   \
+  {                                                                \
+    false, grpc_lb_v0_InitialLoadBalanceResponse_init_zero, false, \
+        grpc_lb_v0_ServerList_init_zero                            \
+  }
+#define grpc_lb_v0_InitialLoadBalanceResponse_init_zero \
+  { false, "", false, "", false, grpc_lb_v0_Duration_init_zero }
+#define grpc_lb_v0_ServerList_init_zero    \
+  {                                        \
+    {                                      \
+      { NULL }                             \
+      , NULL                               \
+    }                                      \
+    , false, grpc_lb_v0_Duration_init_zero \
+  }
+#define grpc_lb_v0_Server_init_zero \
+  { false, "", false, 0, false, {0, {0}}, false, 0 }
+
+/* Field tags (for use in manual encoding/decoding) */
+#define grpc_lb_v0_ClientStats_total_requests_tag 1
+#define grpc_lb_v0_ClientStats_client_rpc_errors_tag 2
+#define grpc_lb_v0_ClientStats_dropped_requests_tag 3
+#define grpc_lb_v0_Duration_seconds_tag 1
+#define grpc_lb_v0_Duration_nanos_tag 2
+#define grpc_lb_v0_InitialLoadBalanceRequest_name_tag 1
+#define grpc_lb_v0_Server_ip_address_tag 1
+#define grpc_lb_v0_Server_port_tag 2
+#define grpc_lb_v0_Server_load_balance_token_tag 3
+#define grpc_lb_v0_Server_drop_request_tag 4
+#define grpc_lb_v0_InitialLoadBalanceResponse_client_config_tag 1
+#define grpc_lb_v0_InitialLoadBalanceResponse_load_balancer_delegate_tag 2
+#define grpc_lb_v0_InitialLoadBalanceResponse_client_stats_report_interval_tag 3
+#define grpc_lb_v0_LoadBalanceRequest_initial_request_tag 1
+#define grpc_lb_v0_LoadBalanceRequest_client_stats_tag 2
+#define grpc_lb_v0_ServerList_servers_tag 1
+#define grpc_lb_v0_ServerList_expiration_interval_tag 3
+#define grpc_lb_v0_LoadBalanceResponse_initial_response_tag 1
+#define grpc_lb_v0_LoadBalanceResponse_server_list_tag 2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t grpc_lb_v0_Duration_fields[3];
+extern const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3];
+extern const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2];
+extern const pb_field_t grpc_lb_v0_ClientStats_fields[4];
+extern const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3];
+extern const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4];
+extern const pb_field_t grpc_lb_v0_ServerList_fields[3];
+extern const pb_field_t grpc_lb_v0_Server_fields[5];
+
+/* Maximum encoded size of messages (where known) */
+#define grpc_lb_v0_Duration_size 22
+#define grpc_lb_v0_LoadBalanceRequest_size 169
+#define grpc_lb_v0_InitialLoadBalanceRequest_size 131
+#define grpc_lb_v0_ClientStats_size 33
+#define grpc_lb_v0_InitialLoadBalanceResponse_size 156
+#define grpc_lb_v0_Server_size 127
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define LOAD_BALANCER_MESSAGES
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/src/proto/grpc/lb/v0/load_balancer.options b/src/proto/grpc/lb/v0/load_balancer.options
new file mode 100644
index 0000000000000000000000000000000000000000..6d4528f838a4c819c5b183bac9edb2db67200356
--- /dev/null
+++ b/src/proto/grpc/lb/v0/load_balancer.options
@@ -0,0 +1,6 @@
+grpc.lb.v0.InitialLoadBalanceRequest.name max_size:128
+grpc.lb.v0.InitialLoadBalanceResponse.client_config max_size:64
+grpc.lb.v0.InitialLoadBalanceResponse.load_balancer_delegate max_size:64
+grpc.lb.v0.Server.ip_address max_size:46
+grpc.lb.v0.Server.load_balance_token max_size:64
+load_balancer.proto no_unions:true
diff --git a/src/proto/grpc/lb/v0/load_balancer.proto b/src/proto/grpc/lb/v0/load_balancer.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e88a4f8c4a7eb7e949daeadfc61becd108a41737
--- /dev/null
+++ b/src/proto/grpc/lb/v0/load_balancer.proto
@@ -0,0 +1,144 @@
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package grpc.lb.v0;
+
+message Duration {
+
+  // Signed seconds of the span of time. Must be from -315,576,000,000
+  // to +315,576,000,000 inclusive.
+  int64 seconds = 1;
+
+  // Signed fractions of a second at nanosecond resolution of the span
+  // of time. Durations less than one second are represented with a 0
+  // `seconds` field and a positive or negative `nanos` field. For durations
+  // of one second or more, a non-zero value for the `nanos` field must be
+  // of the same sign as the `seconds` field. Must be from -999,999,999
+  // to +999,999,999 inclusive.
+  int32 nanos = 2;
+}
+
+service LoadBalancer {
+  // Bidirectional rpc to get a list of servers.
+  rpc BalanceLoad(stream LoadBalanceRequest)
+      returns (stream LoadBalanceResponse);
+}
+
+message LoadBalanceRequest {
+  oneof load_balance_request_type {
+    // This message should be sent on the first request to the load balancer.
+    InitialLoadBalanceRequest initial_request = 1;
+
+    // The client stats should be periodically reported to the load balancer
+    // based on the duration defined in the InitialLoadBalanceResponse.
+    ClientStats client_stats = 2;
+  }
+}
+
+message InitialLoadBalanceRequest {
+  // Name of load balanced service (IE, service.grpc.gslb.google.com)
+  string name = 1;
+}
+
+// Contains client level statistics that are useful to load balancing. Each
+// count should be reset to zero after reporting the stats.
+message ClientStats {
+  // The total number of requests sent by the client since the last report.
+  int64 total_requests = 1;
+
+  // The number of client rpc errors since the last report.
+  int64 client_rpc_errors = 2;
+
+  // The number of dropped requests since the last report.
+  int64 dropped_requests = 3;
+}
+
+message LoadBalanceResponse {
+  oneof load_balance_response_type {
+    // This message should be sent on the first response to the client.
+    InitialLoadBalanceResponse initial_response = 1;
+
+    // Contains the list of servers selected by the load balancer. The client
+    // should send requests to these servers in the specified order.
+    ServerList server_list = 2;
+  }
+}
+
+message InitialLoadBalanceResponse {
+  oneof initial_response_type {
+    // Contains gRPC config options like RPC deadline or flow control.
+    // TODO(yetianx): Change to ClientConfig after it is defined.
+    string client_config = 1;
+
+    // This is an application layer redirect that indicates the client should
+    // use the specified server for load balancing. When this field is set in
+    // the response, the client should open a separate connection to the
+    // load_balancer_delegate and call the BalanceLoad method.
+    string load_balancer_delegate = 2;
+  }
+
+  // This interval defines how often the client should send the client stats
+  // to the load balancer. Stats should only be reported when the duration is
+  // positive.
+  Duration client_stats_report_interval = 3;
+}
+
+message ServerList {
+  // Contains a list of servers selected by the load balancer. The list will
+  // be updated when server resolutions change or as needed to balance load
+  // across more servers. The client should consume the server list in order
+  // unless instructed otherwise via the client_config.
+  repeated Server servers = 1;
+
+  // Indicates the amount of time that the client should consider this server
+  // list as valid. It may be considered stale after waiting this interval of
+  // time after receiving the list. If the interval is not positive, the
+  // client can assume the list is valid until the next list is received.
+  Duration expiration_interval = 3;
+}
+
+message Server {
+  // A resolved address and port for the server. The IP address string may
+  // either be an IPv4 or IPv6 address.
+  string ip_address = 1;
+  int32 port = 2;
+
+  // An opaque token that is passed from the client to the server in metadata.
+  // The server may expect this token to indicate that the request from the
+  // client was load balanced.
+  // TODO(yetianx): Not used right now, and will be used after implementing
+  // load report.
+  bytes load_balance_token = 3;
+
+  // Indicates whether this particular request should be dropped by the client
+  // when this server is chosen from the list.
+  bool drop_request = 4;
+}
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 8e90f7a61d2fd5070f7b660b5e74c0a306f2ad23..60af862305571d4f46bc1900d3cbfc19618bb1ca 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -109,6 +109,7 @@ CORE_SOURCE_FILES = [
   'src/core/client_config/connector.c',
   'src/core/client_config/default_initial_connect_string.c',
   'src/core/client_config/initial_connect_string.c',
+  'src/core/client_config/lb_policies/load_balancer_api.c',
   'src/core/client_config/lb_policies/pick_first.c',
   'src/core/client_config/lb_policies/round_robin.c',
   'src/core/client_config/lb_policy.c',
@@ -172,6 +173,7 @@ CORE_SOURCE_FILES = [
   'src/core/json/json_reader.c',
   'src/core/json/json_string.c',
   'src/core/json/json_writer.c',
+  'src/core/proto/grpc/lb/v0/load_balancer.pb.c',
   'src/core/surface/alarm.c',
   'src/core/surface/api_trace.c',
   'src/core/surface/byte_buffer.c',
@@ -226,6 +228,9 @@ CORE_SOURCE_FILES = [
   'src/core/census/operation.c',
   'src/core/census/placeholders.c',
   'src/core/census/tracing.c',
+  'third_party/nanopb/pb_common.c',
+  'third_party/nanopb/pb_decode.c',
+  'third_party/nanopb/pb_encode.c',
   'src/boringssl/err_data.c',
   'third_party/boringssl/crypto/aes/aes.c',
   'third_party/boringssl/crypto/aes/mode_wrappers.c',
diff --git a/templates/tools/run_tests/sources_and_headers.json.template b/templates/tools/run_tests/sources_and_headers.json.template
index 04802772af50d362554c6f1426aed04515506411..78363ff1fae66e554be103f9721952f5a4454ee8 100644
--- a/templates/tools/run_tests/sources_and_headers.json.template
+++ b/templates/tools/run_tests/sources_and_headers.json.template
@@ -12,20 +12,27 @@
   			out.extend(fmt % name for fmt in ['%s.grpc.pb.h', '%s.pb.h'])
   	return out
   
-  def no_protos(src):
+  def no_protos_filter(src):
+  	return os.path.splitext(src)[1] != '.proto'
+
+  def no_third_party_filter(src):
+  	return not src.startswith('third_party/')
+  
+  def filter_srcs(srcs, filters):
   	out = []
-  	for f in src:
-  		if os.path.splitext(f)[1] != '.proto':
-  			out.append(f)
+  	for s in srcs:
+  		filter_passes = (f(s) for f in filters)
+  		if all(filter_passes):
+  			out.append(s)
   	return out
   %>
   
   ${json.dumps([{"name": tgt.name,
                  "language": tgt.language,
                  "src": sorted(
-                     no_protos(tgt.src) + 
-                     tgt.get('public_headers', []) + 
-                     tgt.get('headers', [])),
+                     filter_srcs(tgt.src, (no_protos_filter, no_third_party_filter)) + 
+                     filter_srcs(tgt.get('public_headers', []), (no_protos_filter, no_third_party_filter)) + 
+                     filter_srcs(tgt.get('headers', []), (no_third_party_filter,))),
                  "headers": sorted(
                      tgt.get('public_headers', []) + 
                      tgt.get('headers', []) + 
diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bd4885fb4cd3659e2e0d85d6b263eb767f0ece6c
--- /dev/null
+++ b/test/cpp/grpclb/grpclb_api_test.cc
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "src/core/client_config/lb_policies/load_balancer_api.h"
+#include "src/proto/grpc/lb/v0/load_balancer.pb.h"  // C++ version
+
+namespace grpc {
+namespace {
+
+using grpc::lb::v0::LoadBalanceRequest;
+using grpc::lb::v0::LoadBalanceResponse;
+
+class GrpclbTest : public ::testing::Test {};
+
+TEST_F(GrpclbTest, CreateRequest) {
+  const std::string service_name = "AServiceName";
+  LoadBalanceRequest request;
+  grpc_grpclb_request* c_req = grpc_grpclb_request_create(service_name.c_str());
+  gpr_slice slice = grpc_grpclb_request_encode(c_req);
+  const int num_bytes_written = GPR_SLICE_LENGTH(slice);
+  EXPECT_GT(num_bytes_written, 0);
+  request.ParseFromArray(GPR_SLICE_START_PTR(slice), num_bytes_written);
+  EXPECT_EQ(request.initial_request().name(), service_name);
+  gpr_slice_unref(slice);
+  grpc_grpclb_request_destroy(c_req);
+}
+
+TEST_F(GrpclbTest, ParseResponse) {
+  LoadBalanceResponse response;
+  const std::string client_config_str = "I'm a client config";
+  auto* initial_response = response.mutable_initial_response();
+  initial_response->set_client_config(client_config_str);
+  auto* client_stats_report_interval =
+      initial_response->mutable_client_stats_report_interval();
+  client_stats_report_interval->set_seconds(123);
+  client_stats_report_interval->set_nanos(456);
+
+  const std::string encoded_response = response.SerializeAsString();
+  gpr_slice encoded_slice =
+      gpr_slice_from_copied_string(encoded_response.c_str());
+  grpc_grpclb_response* c_response = grpc_grpclb_response_parse(encoded_slice);
+  EXPECT_TRUE(c_response->has_initial_response);
+  EXPECT_TRUE(c_response->initial_response.has_client_config);
+  EXPECT_FALSE(c_response->initial_response.has_load_balancer_delegate);
+  EXPECT_TRUE(strcmp(c_response->initial_response.client_config,
+                     client_config_str.c_str()) == 0);
+  EXPECT_EQ(c_response->initial_response.client_stats_report_interval.seconds,
+            123);
+  EXPECT_EQ(c_response->initial_response.client_stats_report_interval.nanos,
+            456);
+  gpr_slice_unref(encoded_slice);
+  grpc_grpclb_response_destroy(c_response);
+}
+
+TEST_F(GrpclbTest, ParseResponseServerList) {
+  LoadBalanceResponse response;
+  auto* serverlist = response.mutable_server_list();
+  auto* server = serverlist->add_servers();
+  server->set_ip_address("127.0.0.1");
+  server->set_port(12345);
+  server->set_drop_request(true);
+  server = response.mutable_server_list()->add_servers();
+  server->set_ip_address("10.0.0.1");
+  server->set_port(54321);
+  server->set_drop_request(false);
+  auto* expiration_interval = serverlist->mutable_expiration_interval();
+  expiration_interval->set_seconds(888);
+  expiration_interval->set_nanos(999);
+
+  const std::string encoded_response = response.SerializeAsString();
+  gpr_slice encoded_slice =
+      gpr_slice_from_copied_string(encoded_response.c_str());
+  grpc_grpclb_serverlist* c_serverlist =
+      grpc_grpclb_response_parse_serverlist(encoded_slice);
+  ASSERT_EQ(c_serverlist->num_servers, 2ul);
+  EXPECT_TRUE(c_serverlist->servers[0]->has_ip_address);
+  EXPECT_TRUE(strcmp(c_serverlist->servers[0]->ip_address, "127.0.0.1") == 0);
+  EXPECT_EQ(c_serverlist->servers[0]->port, 12345);
+  EXPECT_TRUE(c_serverlist->servers[0]->drop_request);
+  EXPECT_TRUE(c_serverlist->servers[1]->has_ip_address);
+  EXPECT_TRUE(strcmp(c_serverlist->servers[1]->ip_address, "10.0.0.1") == 0);
+  EXPECT_EQ(c_serverlist->servers[1]->port, 54321);
+  EXPECT_FALSE(c_serverlist->servers[1]->drop_request);
+
+  EXPECT_TRUE(c_serverlist->expiration_interval.has_seconds);
+  EXPECT_EQ(c_serverlist->expiration_interval.seconds, 888);
+  EXPECT_TRUE(c_serverlist->expiration_interval.has_nanos);
+  EXPECT_EQ(c_serverlist->expiration_interval.nanos, 999);
+
+  gpr_slice_unref(encoded_slice);
+  grpc_grpclb_destroy_serverlist(c_serverlist);
+}
+
+}  // namespace
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/third_party/nanopb b/third_party/nanopb
new file mode 160000
index 0000000000000000000000000000000000000000..5497a1dfc91a86965383cdd1652e348345400435
--- /dev/null
+++ b/third_party/nanopb
@@ -0,0 +1 @@
+Subproject commit 5497a1dfc91a86965383cdd1652e348345400435
diff --git a/tools/codegen/core/gen_load_balancing_proto.sh b/tools/codegen/core/gen_load_balancing_proto.sh
new file mode 100755
index 0000000000000000000000000000000000000000..114dd9d70d827cb16fb28700361b38ec22a52dfc
--- /dev/null
+++ b/tools/codegen/core/gen_load_balancing_proto.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#
+# Example usage:
+#   tools/codegen/core/gen_load_balancing_proto.sh \
+#     src/proto/grpc/lb/v0/load_balancer.proto
+
+read -r -d '' COPYRIGHT <<'EOF'
+/*
+ *
+ * Copyright <YEAR>, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+EOF
+
+# build clang-format docker image
+docker build -t grpc_clang_format tools/dockerfile/grpc_clang_format
+
+CURRENT_YEAR=$(date +%Y)
+COPYRIGHT_FILE=$(mktemp)
+echo "${COPYRIGHT/<YEAR>/$CURRENT_YEAR}" > $COPYRIGHT_FILE
+
+set -ex
+if [ $# -eq 0 ]; then
+  echo "Usage: $0 <load_balancer.proto> [output dir]"
+  exit 1
+fi
+
+readonly GRPC_ROOT=$PWD
+
+OUTPUT_DIR="$GRPC_ROOT/src/core/proto/grpc/lb/v0"
+if [ $# -eq 2 ]; then
+  mkdir -p "$2"
+  if [ $? != 0 ]; then
+    echo "Error creating output directory $2"
+    exit 2
+  fi
+  OUTPUT_DIR="$2"
+fi
+
+readonly EXPECTED_OPTIONS_FILE_PATH="${1%.*}.options"
+
+if [[ ! -f "$1" ]]; then
+  echo "Input proto file '$1' doesn't exist."
+  exit 3
+fi
+if [[ ! -f "${EXPECTED_OPTIONS_FILE_PATH}" ]]; then
+  echo "Expected nanopb options file '${EXPECTED_OPTIONS_FILE_PATH}' missing"
+  exit 4
+fi
+
+pushd "$(dirname $1)" > /dev/null
+
+protoc \
+--plugin=protoc-gen-nanopb="$GRPC_ROOT/third_party/nanopb/generator/protoc-gen-nanopb" \
+--nanopb_out='-T -L#include\ \"third_party/nanopb/pb.h\"'":$OUTPUT_DIR" \
+"$(basename $1)"
+
+readonly PROTO_BASENAME=$(basename $1 .proto)
+sed -i "s:$PROTO_BASENAME.pb.h:src/core/proto/grpc/lb/v0/$PROTO_BASENAME.pb.h:g" \
+    "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
+
+# prepend copyright
+TMPFILE=$(mktemp)
+cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c" > $TMPFILE
+mv -v $TMPFILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
+cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.h" > $TMPFILE
+mv -v $TMPFILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.h"
+
+readonly MOUNTPOINT='/protos'
+docker run --rm=true -v ${HOST_GIT_ROOT}/gens/src/proto/grpc/lb/v0:$MOUNTPOINT \
+        -t grpc_clang_format \
+        clang-format-3.6 -style="{BasedOnStyle: Google, Language: Cpp}" \
+        -i $MOUNTPOINT/load_balancer.pb.c $MOUNTPOINT/load_balancer.pb.h
+
+popd > /dev/null
diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh
new file mode 100755
index 0000000000000000000000000000000000000000..78d3a734e96f93b0da19eeaf21a2157038dab054
--- /dev/null
+++ b/tools/distrib/check_nanopb_output.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+apt-get install -y autoconf automake libtool curl python-virtualenv
+
+readonly NANOPB_TMP_OUTPUT="${LOCAL_GIT_ROOT}/gens/src/proto/grpc/lb/v0"
+readonly VENV_DIR=$(mktemp -d)
+# create a virtualenv for nanopb's compiler
+pushd $VENV_DIR
+readonly VENV_NAME="nanopb-$(date '+%Y%m%d_%H%M%S_%N')"
+virtualenv $VENV_NAME
+. $VENV_NAME/bin/activate
+popd
+
+# install proto3
+pip install protobuf==3.0.0b2
+
+# change to root directory
+cd $(dirname $0)/../..
+
+# build clang-format docker image
+docker build -t grpc_clang_format tools/dockerfile/grpc_clang_format
+
+# install protoc version 3
+pushd third_party/protobuf
+./autogen.sh
+./configure
+make
+make install
+ldconfig
+popd
+
+if [ ! -x "/usr/local/bin/protoc" ]; then
+  echo "Error: protoc not found in path"
+  exit 1
+fi
+readonly PROTOC_PATH='/usr/local/bin'
+# stack up and change to nanopb's proto generator directory
+pushd third_party/nanopb/generator/proto
+PATH="$PROTOC_PATH:$PATH" make
+
+# back to the root directory
+popd
+
+
+# nanopb-compile the proto to a temp location
+PATH="$PROTOC_PATH:$PATH" ./tools/codegen/core/gen_load_balancing_proto.sh \
+  src/proto/grpc/lb/v0/load_balancer.proto \
+  $NANOPB_TMP_OUTPUT
+
+# compare outputs to checked compiled code
+diff -rq $NANOPB_TMP_OUTPUT src/core/proto/grpc/lb/v0
+if [ $? != 0 ]; then
+  echo "Outputs differ: $NANOPB_TMP_OUTPUT vs src/core/proto/grpc/lb/v0"
+  exit 1
+fi
+deactivate
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b6268432335e763b99881e002a37d229fbb34931..c6f1b6ae7c2db30f4a003abdcc01d6c295068e7c 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -801,6 +801,7 @@ src/core/channel/subchannel_call_holder.h \
 src/core/client_config/client_config.h \
 src/core/client_config/connector.h \
 src/core/client_config/initial_connect_string.h \
+src/core/client_config/lb_policies/load_balancer_api.h \
 src/core/client_config/lb_policies/pick_first.h \
 src/core/client_config/lb_policies/round_robin.h \
 src/core/client_config/lb_policy.h \
@@ -861,6 +862,7 @@ src/core/json/json.h \
 src/core/json/json_common.h \
 src/core/json/json_reader.h \
 src/core/json/json_writer.h \
+src/core/proto/grpc/lb/v0/load_balancer.pb.h \
 src/core/statistics/census_interface.h \
 src/core/statistics/census_rpc_stats.h \
 src/core/surface/api_trace.h \
@@ -902,6 +904,10 @@ src/core/transport/transport.h \
 src/core/transport/transport_impl.h \
 src/core/census/aggregation.h \
 src/core/census/rpc_metric_id.h \
+third_party/nanopb/pb.h \
+third_party/nanopb/pb_common.h \
+third_party/nanopb/pb_decode.h \
+third_party/nanopb/pb_encode.h \
 src/core/httpcli/httpcli_security_connector.c \
 src/core/security/base64.c \
 src/core/security/client_auth_filter.c \
@@ -938,6 +944,7 @@ src/core/client_config/client_config.c \
 src/core/client_config/connector.c \
 src/core/client_config/default_initial_connect_string.c \
 src/core/client_config/initial_connect_string.c \
+src/core/client_config/lb_policies/load_balancer_api.c \
 src/core/client_config/lb_policies/pick_first.c \
 src/core/client_config/lb_policies/round_robin.c \
 src/core/client_config/lb_policy.c \
@@ -1001,6 +1008,7 @@ src/core/json/json.c \
 src/core/json/json_reader.c \
 src/core/json/json_string.c \
 src/core/json/json_writer.c \
+src/core/proto/grpc/lb/v0/load_balancer.pb.c \
 src/core/surface/alarm.c \
 src/core/surface/api_trace.c \
 src/core/surface/byte_buffer.c \
@@ -1055,6 +1063,9 @@ src/core/census/initialize.c \
 src/core/census/operation.c \
 src/core/census/placeholders.c \
 src/core/census/tracing.c \
+third_party/nanopb/pb_common.c \
+third_party/nanopb/pb_decode.c \
+third_party/nanopb/pb_encode.c \
 include/grpc/support/alloc.h \
 include/grpc/support/atm.h \
 include/grpc/support/atm_gcc_atomic.h \
diff --git a/tools/jenkins/build_docker_and_run_tests.sh b/tools/jenkins/build_docker_and_run_tests.sh
index e2ac7518f09992e9088852df21ca8cfe92d8fe75..daa29b2f94bba59cfd64ef0a3164175c04e54fbb 100755
--- a/tools/jenkins/build_docker_and_run_tests.sh
+++ b/tools/jenkins/build_docker_and_run_tests.sh
@@ -60,6 +60,9 @@ docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
 # Choose random name for docker container
 CONTAINER_NAME="run_tests_$(uuidgen)"
 
+# Git root as seen by the docker instance
+docker_instance_git_root=/var/local/jenkins/grpc
+
 # Run tests inside docker
 docker run \
   -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \
@@ -69,9 +72,10 @@ docker run \
   -e XDG_CACHE_HOME=/tmp/xdg-cache-home \
   -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
   -e HOST_GIT_ROOT=$git_root \
+  -e LOCAL_GIT_ROOT=$docker_instance_git_root \
   -e "BUILD_ID=$BUILD_ID" \
   -i $TTY_FLAG \
-  -v "$git_root:/var/local/jenkins/grpc" \
+  -v "$git_root:$docker_instance_git_root" \
   -v /tmp/ccache:/tmp/ccache \
   -v /tmp/npm-cache:/tmp/npm-cache \
   -v /tmp/xdg-cache-home:/tmp/xdg-cache-home \
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index f49230e49aa44cc3de8ea83be8bb49bbe81240c0..c08b382638fbd4f4e14be9be6f67dfd262301b88 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -44,6 +44,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules
  9f897b25800d2f54f5c442ef01a60721aeca6d87 third_party/boringssl (version_for_cocoapods_1.0-67-g9f897b2)
  05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
+ 5497a1dfc91a86965383cdd1652e348345400435 third_party/nanopb (nanopb-0.3.3-10-g5497a1d)
  d5fb408ddc281ffcadeb08699e65bb694656d0bd third_party/protobuf (v3.0.0-beta-2)
  50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
 EOF
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 809e6ce645414fe527b9112c4dc1c5d715c1f592..1fc0525e0297cc011ad7a3e8d64da28a17caff8d 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -7,3 +7,4 @@
 - script: tools/distrib/check_copyright.py
 - script: tools/distrib/clang_format_code.sh
 - script: tools/distrib/check_trailing_newlines.sh
+- script: tools/distrib/check_nanopb_output.sh
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 6538ddc37e1941939f398f3606620b411d7eaf86..76fa3d077644f80953e9d4fec04236eb57461744 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1644,6 +1644,23 @@
       "src/compiler/ruby_plugin.cc"
     ]
   }, 
+  {
+    "deps": [
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/lb/v0/load_balancer.grpc.pb.h", 
+      "src/proto/grpc/lb/v0/load_balancer.pb.h"
+    ], 
+    "language": "c++", 
+    "name": "grpclb_api_test", 
+    "src": [
+      "test/cpp/grpclb/grpclb_api_test.cc"
+    ]
+  }, 
   {
     "deps": [
       "gpr", 
@@ -2983,6 +3000,7 @@
       "src/core/client_config/client_config.h", 
       "src/core/client_config/connector.h", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.h", 
       "src/core/client_config/lb_policy.h", 
@@ -3043,6 +3061,7 @@
       "src/core/json/json_common.h", 
       "src/core/json/json_reader.h", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/security/auth_filters.h", 
       "src/core/security/base64.h", 
       "src/core/security/credentials.h", 
@@ -3095,7 +3114,11 @@
       "src/core/tsi/ssl_transport_security.h", 
       "src/core/tsi/ssl_types.h", 
       "src/core/tsi/transport_security.h", 
-      "src/core/tsi/transport_security_interface.h"
+      "src/core/tsi/transport_security_interface.h", 
+      "third_party/nanopb/pb.h", 
+      "third_party/nanopb/pb_common.h", 
+      "third_party/nanopb/pb_decode.h", 
+      "third_party/nanopb/pb_encode.h"
     ], 
     "language": "c", 
     "name": "grpc", 
@@ -3149,6 +3172,8 @@
       "src/core/client_config/default_initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.c", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.c", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.c", 
@@ -3273,6 +3298,8 @@
       "src/core/json/json_string.c", 
       "src/core/json/json_writer.c", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.c", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/security/auth_filters.h", 
       "src/core/security/base64.c", 
       "src/core/security/base64.h", 
@@ -3508,6 +3535,7 @@
       "src/core/client_config/client_config.h", 
       "src/core/client_config/connector.h", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.h", 
       "src/core/client_config/lb_policy.h", 
@@ -3568,6 +3596,7 @@
       "src/core/json/json_common.h", 
       "src/core/json/json_reader.h", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/statistics/census_interface.h", 
       "src/core/statistics/census_rpc_stats.h", 
       "src/core/surface/api_trace.h", 
@@ -3606,7 +3635,11 @@
       "src/core/transport/metadata_batch.h", 
       "src/core/transport/static_metadata.h", 
       "src/core/transport/transport.h", 
-      "src/core/transport/transport_impl.h"
+      "src/core/transport/transport_impl.h", 
+      "third_party/nanopb/pb.h", 
+      "third_party/nanopb/pb_common.h", 
+      "third_party/nanopb/pb_decode.h", 
+      "third_party/nanopb/pb_encode.h"
     ], 
     "language": "c", 
     "name": "grpc_unsecure", 
@@ -3659,6 +3692,8 @@
       "src/core/client_config/default_initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.c", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.c", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.c", 
@@ -3782,6 +3817,8 @@
       "src/core/json/json_string.c", 
       "src/core/json/json_writer.c", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.c", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/statistics/census_interface.h", 
       "src/core/statistics/census_rpc_stats.h", 
       "src/core/surface/alarm.c", 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 2c73c40d1f5d08a4f2cc9f1fd93d19f87ab14e94..3b9bce1ec38fc456682daf26c8a90672c0d4981b 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2019,6 +2019,26 @@
       "windows"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "grpclb_api_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 76975322be8390aedde70a6c2f70600d18961ac4..4e1155f84b52e6c978c482751cf41e398398c3c3 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -310,6 +310,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\client_config.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policy.h" />
@@ -370,6 +371,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_rpc_stats.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\api_trace.h" />
@@ -411,6 +413,10 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\core\httpcli\httpcli_security_connector.c">
@@ -485,6 +491,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.c">
@@ -611,6 +619,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\api_trace.c">
@@ -719,6 +729,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 4660572f9799df54d77972425dbedd666c8830e8..e0cfd8295b1400e40f3a65cd0c32c686cf8a8f0d 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -109,6 +109,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
       <Filter>src\core\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClCompile>
@@ -298,6 +301,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
       <Filter>src\core\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -460,6 +466,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
@@ -587,6 +602,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h">
       <Filter>src\core\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClInclude>
@@ -767,6 +785,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h">
       <Filter>src\core\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h">
       <Filter>src\core\statistics</Filter>
     </ClInclude>
@@ -890,6 +911,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -941,6 +974,18 @@
     <Filter Include="src\core\json">
       <UniqueIdentifier>{e665cc0e-b994-d7c5-cc18-2007392019f0}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\proto">
+      <UniqueIdentifier>{1ff04466-0905-8a5d-d6f4-7ff2df4c13b5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc">
+      <UniqueIdentifier>{7c7ad0b3-bf85-5bd3-e0c8-4f5468a8e2e6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb">
+      <UniqueIdentifier>{3d533dad-8100-e8a3-b7c3-1fc13a4d60da}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb\v0">
+      <UniqueIdentifier>{0ffcf868-7617-5fed-b6ce-2162d9d09148}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\security">
       <UniqueIdentifier>{1d850ac6-e639-4eab-5338-4ba40272fcc9}</UniqueIdentifier>
     </Filter>
@@ -959,6 +1004,12 @@
     <Filter Include="src\core\tsi">
       <UniqueIdentifier>{0b0f9ab1-efa4-7f03-e446-6fb9b5227e84}</UniqueIdentifier>
     </Filter>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{aaab30a4-2a15-732e-c141-3fbc0f0f5a7a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\nanopb">
+      <UniqueIdentifier>{93d6596d-330c-1d27-6f84-3c840e57869e}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 541000af4041c7761255a778599807e9e68ea9ed..3820d89968ba57b1e0cf7a9c5c042f0bd3712663 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -286,6 +286,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\client_config.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policy.h" />
@@ -346,6 +347,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_rpc_stats.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\api_trace.h" />
@@ -387,6 +389,10 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\init_unsecure.c">
@@ -421,6 +427,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.c">
@@ -547,6 +555,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\api_trace.c">
@@ -655,6 +665,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 48814f997e103d5f582f94c594e9eda5389a3eb1..c4c957d36b2be5ea4394de09caa549ce4799ca7c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -49,6 +49,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
       <Filter>src\core\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClCompile>
@@ -238,6 +241,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
       <Filter>src\core\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -400,6 +406,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
@@ -482,6 +497,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h">
       <Filter>src\core\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClInclude>
@@ -662,6 +680,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h">
       <Filter>src\core\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h">
       <Filter>src\core\statistics</Filter>
     </ClInclude>
@@ -785,6 +806,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -836,6 +869,18 @@
     <Filter Include="src\core\json">
       <UniqueIdentifier>{443ffc61-1bea-2477-6e54-1ddf8c139264}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\proto">
+      <UniqueIdentifier>{7f4bb22a-65ba-0f8f-6387-66b1f6677a80}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc">
+      <UniqueIdentifier>{9c2bd164-c317-8a13-564d-3b28b0fd79cf}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb">
+      <UniqueIdentifier>{2bad8e10-4fc5-d8b3-e026-4abbd0c25cda}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb\v0">
+      <UniqueIdentifier>{4475c8ed-e01b-8906-47d0-8a504189c0d5}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\statistics">
       <UniqueIdentifier>{e084164c-a069-00e3-db35-4e0b1cd6f0b7}</UniqueIdentifier>
     </Filter>
@@ -848,6 +893,12 @@
     <Filter Include="src\core\transport\chttp2">
       <UniqueIdentifier>{5fcd6206-f774-9ae6-4b85-305d6a723843}</UniqueIdentifier>
     </Filter>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{025c051e-8eba-125b-67f9-173f95176eb2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\nanopb">
+      <UniqueIdentifier>{6511f77d-f28c-80e0-0889-8975e688e344}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..1509ece9f96a82b1ac74129593f6c07794df1bb6
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{990AF023-17D7-8DBF-EB6E-14C7C016C77E}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>grpclb_api_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>grpclb_api_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\grpclb\grpclb_api_test.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+      <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj.filters b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..6c57b8c162a7e34d7ead3fbf32e691069a1f8b5e
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj.filters
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.proto">
+      <Filter>src\proto\grpc\lb\v0</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\grpclb\grpclb_api_test.cc">
+      <Filter>test\cpp\grpclb</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{a31d21fb-c6ab-75ce-43dc-7d6f506765e6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{10d49c90-8503-9b10-6678-eed983bc25d9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{8b6be783-e071-44cc-2096-f1c476012556}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\lb">
+      <UniqueIdentifier>{2981699e-c196-c599-bc17-c177770f89ee}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\lb\v0">
+      <UniqueIdentifier>{3d04774a-1c2f-e100-435e-08af5d539250}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{64736e1d-eb77-664f-34ab-6cf41263d3d8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{c86e9cb1-bed4-3697-40f2-9ecff6297fa5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\grpclb">
+      <UniqueIdentifier>{6b5ba83a-6cf2-5a7b-0ab8-62de31882705}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+