diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index e10e05387b15a81436577ed9cdf187d5ec137159..4811abf698baefc6e824c256c5039f60f78b5933 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -193,7 +193,6 @@ Pod::Spec.new do |s|
     ss.dependency "#{s.name}/Interface", version
     ss.dependency 'BoringSSL', '~> 4.0'
 
-    # To save you from scrolling, this is the last part of the podspec.
     ss.source_files = 'src/core/lib/profiling/timers.h',
                       'src/core/lib/support/backoff.h',
                       'src/core/lib/support/block_annotate.h',
@@ -759,4 +758,26 @@ Pod::Spec.new do |s|
                               'src/core/ext/census/mlog.h',
                               'src/core/ext/census/rpc_metric_id.h'
   end
+  
+  s.subspec 'Cronet-Interface' do |ss|
+    ss.header_mappings_dir = 'include/grpc'
+    ss.source_files = 'include/grpc/grpc_cronet.h'
+  end
+
+  s.subspec 'Cronet-Tests' do |ss|
+    ss.header_mappings_dir = '.'
+
+    ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
+                      'src/core/ext/transport/cronet/transport/cronet_transport.c',
+                      'test/core/end2end/cq_verifier.{c,h}',
+                      'test/core/end2end/end2end_tests.{c,h}',
+                      'test/core/end2end/tests/*.{c,h}',
+                      'test/core/end2end/data/*.{c,h}',
+                      'test/core/util/test_config.{c,h}',
+                      'test/core/util/port.h',
+                      'test/core/util/port_posix.c',
+                      'test/core/util/port_server_client.{c,h}'
+
+    ss.dependency 'CronetFramework'
+  end
 end
diff --git a/gRPC-Cronet.podspec b/gRPC-Cronet.podspec
deleted file mode 100644
index b353bf9a43760219fe87bbaa6e6657e9a385da59..0000000000000000000000000000000000000000
--- a/gRPC-Cronet.podspec
+++ /dev/null
@@ -1,117 +0,0 @@
-# GRPC CocoaPods podspec
-# This file has been automatically generated from a template file.
-# Please look at the templates directory instead.
-# This file can be regenerated from the template by running
-# tools/buildgen/generate_projects.sh
-
-# Copyright 2015, 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.
-
-
-Pod::Spec.new do |s|
-  s.name     = 'gRPC-Cronet'
-  version = '0.14.0'
-  s.version  = version
-  s.summary  = 'Integration of CroNet framework into gRPC'
-  s.homepage = 'http://www.grpc.io'
-  s.license  = 'New BSD'
-  s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }
-
-  s.source = {
-    :git => 'https://github.com/grpc/grpc.git',
-    :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}",
-  }
-
-  s.ios.deployment_target = '7.1'
-  s.osx.deployment_target = '10.9'
-  s.requires_arc = false
-
-  name = 'GRPCCronet'
-
-  s.module_name = name
-
-  # When creating a dynamic framework, copy the headers under `include/grpc/` into the root of
-  # the `Headers/` directory of the framework (i.e., not under `Headers/include/grpc`).
-  s.header_mappings_dir = 'include/grpc'
-
-  # The above has an undesired effect when creating a static library: It forces users to write
-  # includes like `#include <gRPC-Cronet/grpc.h>`. `s.header_dir` adds a path prefix to that, and
-  # because Cocoapods lets omit the pod name when including headers of static libraries, the
-  # following lets users write `#include <grpc/grpc.h>`.
-  s.header_dir = 'grpc'
-
-  # To compile the library, we need the user headers search path (quoted includes) to point to the
-  # root of the repo, and the system headers search path (angled includes) to point to `include/`.
-  # Cocoapods effectively clones the repo under `<Podfile dir>/Pods/gRPC-Cronet/`, and sets a build
-  # variable called `$(PODS_ROOT)` to `<Podfile dir>/Pods/`, so we use that.
-  #
-  # Relying on the file structure under $(PODS_ROOT) isn't officially supported in Cocoapods, as it
-  # is taken as an implementation detail. We've asked for an alternative, and have been told that
-  # what we're doing should keep working: https://github.com/CocoaPods/CocoaPods/issues/4386
-  #
-  # The `src_root` value of `$(PODS_ROOT)/gRPC-Cronet` assumes Cocoapods is installing this pod from
-  # its remote repo. For local development of this library, enabled by using `:path` in the Podfile,
-  # that assumption is wrong. In such case, the following settings need to be reset with the
-  # appropriate value of `src_root`. This can be accomplished in the `pre_install` hook of the
-  # Podfile; see `src/objective-c/tests/Podfile` for an example.
-  src_root = '$(PODS_ROOT)/gRPC-Cronet'
-  s.pod_target_xcconfig = {
-    'GRPC_SRC_ROOT' => src_root,
-    'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
-    'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
-    # If we don't set these two settings, `include/grpc/support/time.h` and
-    # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
-    # build.
-    'USE_HEADERMAP' => 'NO',
-    'ALWAYS_SEARCH_USER_PATHS' => 'NO',
-  }
-
-  s.subspec 'Interface' do |ss|
-    ss.header_mappings_dir = 'include/grpc'
-    ss.source_files = 'include/grpc/grpc_cronet.h'
-  end
-
-  s.subspec 'Implementation' do |ss|
-    ss.header_mappings_dir = '.'
-
-    ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-                      'src/core/ext/transport/cronet/transport/cronet_transport.c',
-                      'test/core/end2end/cq_verifier.{c,h}',
-                      'test/core/end2end/end2end_tests.{c,h}',
-                      'test/core/end2end/tests/*.{c,h}',
-                      'test/core/end2end/data/*.{c,h}',
-                      'test/core/util/test_config.{c,h}',
-                      'test/core/util/port.h',
-                      'test/core/util/port_posix.c',
-                      'test/core/util/port_server_client.{c,h}'
-
-    ss.dependency 'gRPC-Core', version
-    ss.dependency 'CronetFramework'
-  end
-end
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
new file mode 100644
index 0000000000000000000000000000000000000000..0f07b6682e67d6a47bf3bbc59002442d3130724f
--- /dev/null
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
@@ -0,0 +1,39 @@
+//
+//  CoreCronetEnd2EndTests.m
+//  CoreCronetEnd2EndTests
+//
+//  Created by Muxi Yan on 7/14/16.
+//  Copyright © 2016 gRPC. All rights reserved.
+//
+
+#import <XCTest/XCTest.h>
+
+@interface CoreCronetEnd2EndTests : XCTestCase
+
+@end
+
+@implementation CoreCronetEnd2EndTests
+
+- (void)setUp {
+    [super setUp];
+    // Put setup code here. This method is called before the invocation of each test method in the class.
+}
+
+- (void)tearDown {
+    // Put teardown code here. This method is called after the invocation of each test method in the class.
+    [super tearDown];
+}
+
+- (void)testExample {
+    // This is an example of a functional test case.
+    // Use XCTAssert and related functions to verify your tests produce the correct results.
+}
+
+- (void)testPerformanceExample {
+    // This is an example of a performance test case.
+    [self measureBlock:^{
+        // Put the code you want to measure the time of here.
+    }];
+}
+
+@end
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m
new file mode 100644
index 0000000000000000000000000000000000000000..800dd56649a1eb6a9a61dd034f08d9b6d371ad59
--- /dev/null
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/h2_ssl.m
@@ -0,0 +1,206 @@
+/*
+ *
+ * Copyright 2015, 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.
+ *
+ */
+
+/* 
+ * This fixture creates a server full stack using chttp2 and a client
+ * full stack using Cronet. End-to-end tests are run against this fixture
+ * setting.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/security/credentials/credentials.h"
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/string.h"
+#include "src/core/lib/support/tmpfile.h"
+#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+#include <grpc/grpc_cronet.h>
+#import <Cronet/Cronet.h>
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+typedef struct fullstack_secure_fixture_data {
+  char *localaddr;
+} fullstack_secure_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
+    grpc_channel_args *client_args, grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  int port = grpc_pick_unused_port_or_die();
+  fullstack_secure_fixture_data *ffd =
+      gpr_malloc(sizeof(fullstack_secure_fixture_data));
+  memset(&f, 0, sizeof(f));
+
+  gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create(NULL);
+
+  return f;
+}
+
+static void process_auth_failure(void *state, grpc_auth_context *ctx,
+                                 const grpc_metadata *md, size_t md_count,
+                                 grpc_process_auth_metadata_done_cb cb,
+                                 void *user_data) {
+  GPR_ASSERT(state == NULL);
+  cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
+}
+
+static void cronet_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    cronet_engine *cronetEngine) {
+  fullstack_secure_fixture_data *ffd = f->fixture_data;
+  f->client =
+      grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL);
+  GPR_ASSERT(f->client != NULL);
+}
+
+static void chttp2_init_server_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
+    grpc_server_credentials *server_creds) {
+  fullstack_secure_fixture_data *ffd = f->fixture_data;
+  if (f->server) {
+    grpc_server_destroy(f->server);
+  }
+  f->server = grpc_server_create(server_args, NULL);
+  grpc_server_register_completion_queue(f->server, f->cq, NULL);
+  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr,
+                                               server_creds));
+  grpc_server_credentials_release(server_creds);
+  grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
+  fullstack_secure_fixture_data *ffd = f->fixture_data;
+  gpr_free(ffd->localaddr);
+  gpr_free(ffd);
+}
+
+static void cronet_init_client_simple_ssl_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
+  grpc_arg ssl_name_override = {GRPC_ARG_STRING,
+                                GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+                                {"foo.test.google.fr"}};
+  
+  grpc_channel_args *new_client_args =
+      grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
+  [Cronet setHttp2Enabled:YES];
+  [Cronet start];
+  cronet_engine *cronetEngine = [Cronet getGlobalEngine];
+  
+  cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine);
+  grpc_channel_args_destroy(new_client_args);
+}
+
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+  size_t i;
+  if (server_args == NULL) return 0;
+  for (i = 0; i < server_args->num_args; i++) {
+    if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+        0) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static void chttp2_init_server_simple_ssl_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
+  grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
+                                                  test_server1_cert};
+  grpc_server_credentials *ssl_creds =
+      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
+  if (fail_server_auth_check(server_args)) {
+    grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL};
+    grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
+  }
+  chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
+}
+
+/* All test configurations */
+
+static grpc_end2end_test_config configs[] = {
+    {"chttp2/simple_ssl_fullstack",
+     FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
+     chttp2_create_fixture_secure_fullstack,
+     cronet_init_client_simple_ssl_secure_fullstack,
+     chttp2_init_server_simple_ssl_secure_fullstack,
+     chttp2_tear_down_secure_fullstack},
+};
+
+int main(int argc, char **argv) {
+  size_t i;
+  FILE *roots_file;
+  size_t roots_size = strlen(test_root_cert);
+  char *roots_filename;
+
+  grpc_test_init(argc, argv);
+  grpc_end2end_tests_pre_init();
+
+  /* Set the SSL roots env var. */
+  roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename);
+  GPR_ASSERT(roots_filename != NULL);
+  GPR_ASSERT(roots_file != NULL);
+  GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
+  fclose(roots_file);
+  gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
+
+  grpc_init();
+
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_tests(argc, argv, configs[i]);
+  }
+
+  grpc_shutdown();
+
+  /* Cleanup. */
+  remove(roots_filename);
+  gpr_free(roots_filename);
+
+  return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+}
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 30a34260d407cb787f8bebd370515d5a042c90a5..62ffd59f07947402313e65c9eb7a821d21ed47d8 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -18,7 +18,6 @@ GRPC_LOCAL_SRC = '../../..'
   target target_name do
     pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true
     pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true
-    pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
     pod 'gRPC', :path => GRPC_LOCAL_SRC
     pod 'gRPC-Core', :path => GRPC_LOCAL_SRC
     pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC
@@ -27,6 +26,14 @@ GRPC_LOCAL_SRC = '../../..'
   end
 end
 
+target 'CoreCronetEnd2EndTests' do
+  pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true
+  pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
+  pod 'gRPC-Core', :path => GRPC_LOCAL_SRC
+  pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC
+  pod 'gRPC-Core/Cronet-Tests', :path => GRPC_LOCAL_SRC
+end
+
 # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's
 # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded
 # and before they are installed in the user project.
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
index f9389a4977fe695e3daf9d7beabceb0e1834efca..6c41563a350e547e2eb1d66e5445d98ee92967c5 100644
--- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -12,6 +12,10 @@
 		20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; };
 		333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; };
 		3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; };
+		5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */; };
+		5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+		5E8A5DB01D3849F1000F8BC4 /* h2_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */; };
+		60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; };
 		6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
 		63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
 		635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; };
@@ -38,6 +42,13 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 635697C61B14FC11007A7283;
+			remoteInfo = Tests;
+		};
 		63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
@@ -91,12 +102,17 @@
 		060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = "<group>"; };
 		07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
 		0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
+		0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = "<group>"; };
 		20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = "<group>"; };
+		4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = "<group>"; };
 		51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = "<group>"; };
 		553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = "<group>"; };
 		5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = "<group>"; };
+		5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = "<group>"; };
+		5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = h2_ssl.m; sourceTree = "<group>"; };
 		6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = "<group>"; };
 		63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = "<group>"; };
@@ -123,11 +139,21 @@
 		E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = "<group>"; };
 		E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = "<group>"; };
 		E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = "<group>"; };
+		FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+		5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */,
+				60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		63423F411B150A5F006CF63C /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
@@ -194,6 +220,7 @@
 				DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */,
 				A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */,
 				20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */,
+				FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -215,15 +242,27 @@
 				3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */,
 				060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */,
 				E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */,
+				0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */,
+				4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */,
 			);
 			name = Pods;
 			sourceTree = "<group>";
 		};
+		5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = {
+			isa = PBXGroup;
+			children = (
+				5E8A5DAF1D3849F1000F8BC4 /* h2_ssl.m */,
+				5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */,
+			);
+			path = CoreCronetEnd2EndTests;
+			sourceTree = "<group>";
+		};
 		635697BE1B14FC11007A7283 = {
 			isa = PBXGroup;
 			children = (
 				635697C91B14FC11007A7283 /* Tests */,
 				63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */,
+				5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */,
 				635697C81B14FC11007A7283 /* Products */,
 				51E4650F34F854F41FF053B3 /* Pods */,
 				136D535E19727099B941D7B1 /* Frameworks */,
@@ -239,6 +278,7 @@
 				63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */,
 				63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */,
 				63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */,
+				5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -270,6 +310,27 @@
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
+		5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */;
+			buildPhases = (
+				F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */,
+				5E8A5DA01D3840B4000F8BC4 /* Sources */,
+				5E8A5DA11D3840B4000F8BC4 /* Frameworks */,
+				5E8A5DA21D3840B4000F8BC4 /* Resources */,
+				E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */,
+				6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */,
+			);
+			name = CoreCronetEnd2EndTests;
+			productName = CoreCronetEnd2EndTests;
+			productReference = 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
 		63423F431B150A5F006CF63C /* AllTests */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */;
@@ -403,6 +464,9 @@
 				LastUpgradeCheck = 0630;
 				ORGANIZATIONNAME = gRPC;
 				TargetAttributes = {
+					5E8A5DA31D3840B4000F8BC4 = {
+						CreatedOnToolsVersion = 7.3.1;
+					};
 					63423F431B150A5F006CF63C = {
 						CreatedOnToolsVersion = 6.3.1;
 					};
@@ -441,11 +505,19 @@
 				63DC84221BE15267000708E8 /* InteropTestsRemote */,
 				63DC84331BE15294000708E8 /* InteropTestsLocalSSL */,
 				63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */,
+				5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
+		5E8A5DA21D3840B4000F8BC4 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		63423F421B150A5F006CF63C /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -561,6 +633,21 @@
 			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
+		6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
 		7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
@@ -741,9 +828,48 @@
 			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
+		E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
+			showEnvVarsInLog = 0;
+		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+		5E8A5DA01D3840B4000F8BC4 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5E8A5DB01D3849F1000F8BC4 /* h2_ssl.m in Sources */,
+				5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		63423F401B150A5F006CF63C /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -804,6 +930,11 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+		5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 635697C61B14FC11007A7283 /* Tests */;
+			targetProxy = 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */;
+		};
 		63423F4C1B150A5F006CF63C /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 635697C61B14FC11007A7283 /* Tests */;
@@ -832,6 +963,36 @@
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
+		5E8A5DAC1D3840B4000F8BC4 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_TESTABILITY = YES;
+				INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		5E8A5DAD1D3840B4000F8BC4 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
 		63423F4E1B150A5F006CF63C /* Debug */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */;
@@ -1071,6 +1232,15 @@
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+		5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				5E8A5DAC1D3840B4000F8BC4 /* Debug */,
+				5E8A5DAD1D3840B4000F8BC4 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index aefe6e965cc24b3505d779de22e407ad8a08b697..9eeee222713ee74f6c343a414a18e64c12c7afa8 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -128,6 +128,8 @@
       'ALWAYS_SEARCH_USER_PATHS' => 'NO',
     }
 
+    s.default_subspecs = 'Interface', 'Implementation'
+
     # Like many other C libraries, gRPC-Core has its public headers under `include/<libname>/` and its
     # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't
     # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in
@@ -154,4 +156,26 @@
 
       ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)}
     end
+
+    s.subspec 'Cronet-Interface' do |ss|
+      ss.header_mappings_dir = 'include/grpc'
+      ss.source_files = 'include/grpc/grpc_cronet.h'
+    end
+
+    s.subspec 'Cronet-Tests' do |ss|
+      ss.header_mappings_dir = '.'
+
+      ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
+                        'src/core/ext/transport/cronet/transport/cronet_transport.c',
+                        'test/core/end2end/cq_verifier.{c,h}',
+                        'test/core/end2end/end2end_tests.{c,h}',
+                        'test/core/end2end/tests/*.{c,h}',
+                        'test/core/end2end/data/*.{c,h}',
+                        'test/core/util/test_config.{c,h}',
+                        'test/core/util/port.h',
+                        'test/core/util/port_posix.c',
+                        'test/core/util/port_server_client.{c,h}'
+
+      ss.dependency 'CronetFramework'
+    end
   end