diff --git a/Makefile b/Makefile
index aec16ee83ec35ae2847034d4e0eaba82d9979db6..ed75b4cea7c26c592b0e6f712a7c800895adefc4 100644
--- a/Makefile
+++ b/Makefile
@@ -833,6 +833,7 @@ hpack_table_test: $(BINDIR)/$(CONFIG)/hpack_table_test
 httpcli_format_request_test: $(BINDIR)/$(CONFIG)/httpcli_format_request_test
 httpcli_parser_test: $(BINDIR)/$(CONFIG)/httpcli_parser_test
 httpcli_test: $(BINDIR)/$(CONFIG)/httpcli_test
+httpscli_test: $(BINDIR)/$(CONFIG)/httpscli_test
 init_test: $(BINDIR)/$(CONFIG)/init_test
 invalid_call_argument_test: $(BINDIR)/$(CONFIG)/invalid_call_argument_test
 json_rewrite: $(BINDIR)/$(CONFIG)/json_rewrite
@@ -1933,6 +1934,7 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/httpcli_format_request_test \
   $(BINDIR)/$(CONFIG)/httpcli_parser_test \
   $(BINDIR)/$(CONFIG)/httpcli_test \
+  $(BINDIR)/$(CONFIG)/httpscli_test \
   $(BINDIR)/$(CONFIG)/init_test \
   $(BINDIR)/$(CONFIG)/invalid_call_argument_test \
   $(BINDIR)/$(CONFIG)/json_rewrite \
@@ -2964,6 +2966,8 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/httpcli_parser_test || ( echo test httpcli_parser_test failed ; exit 1 )
 	$(E) "[RUN]     Testing httpcli_test"
 	$(Q) $(BINDIR)/$(CONFIG)/httpcli_test || ( echo test httpcli_test failed ; exit 1 )
+	$(E) "[RUN]     Testing httpscli_test"
+	$(Q) $(BINDIR)/$(CONFIG)/httpscli_test || ( echo test httpscli_test failed ; exit 1 )
 	$(E) "[RUN]     Testing init_test"
 	$(Q) $(BINDIR)/$(CONFIG)/init_test || ( echo test init_test failed ; exit 1 )
 	$(E) "[RUN]     Testing invalid_call_argument_test"
@@ -10830,6 +10834,35 @@ endif
 endif
 
 
+HTTPSCLI_TEST_SRC = \
+    test/core/httpcli/httpscli_test.c \
+
+HTTPSCLI_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTPSCLI_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/httpscli_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpscli_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/httpcli/httpscli_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+deps_httpscli_test: $(HTTPSCLI_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(HTTPSCLI_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 INIT_TEST_SRC = \
     test/core/surface/init_test.c \
 
diff --git a/build.yaml b/build.yaml
index 2891b7e19e123be1d49017b795ada180f301822d..3b8b8be94f577a8b27d959e566104b716ea04dcf 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1357,6 +1357,18 @@ targets:
   - mac
   - linux
   - posix
+- name: httpscli_test
+  build: test
+  language: c
+  src:
+  - test/core/httpcli/httpscli_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+  platforms:
+  - linux
 - name: init_test
   build: test
   language: c
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
index a87f1aa87bcba0005f0827f7ca688266b45a8950..b5cd8d8d2acc88dacb92ec3a101c3c7bae205942 100644
--- a/src/core/httpcli/httpcli.c
+++ b/src/core/httpcli/httpcli.c
@@ -53,6 +53,7 @@ typedef struct {
   size_t next_address;
   grpc_endpoint *ep;
   char *host;
+  char *ssl_host_override;
   gpr_timespec deadline;
   int have_read_byte;
   const grpc_httpcli_handshaker *handshaker;
@@ -106,6 +107,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
   }
   gpr_slice_unref(req->request_text);
   gpr_free(req->host);
+  gpr_free(req->ssl_host_override);
   grpc_iomgr_unregister_object(&req->iomgr_obj);
   gpr_slice_buffer_destroy(&req->incoming);
   gpr_slice_buffer_destroy(&req->outgoing);
@@ -180,8 +182,10 @@ static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
     next_address(exec_ctx, req);
     return;
   }
-  req->handshaker->handshake(exec_ctx, req, req->ep, req->host,
-                             on_handshake_done);
+  req->handshaker->handshake(
+      exec_ctx, req, req->ep,
+      req->ssl_host_override ? req->ssl_host_override : req->host,
+      on_handshake_done);
 }
 
 static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) {
@@ -231,6 +235,7 @@ static void internal_request_begin(
   gpr_slice_buffer_init(&req->outgoing);
   grpc_iomgr_register_object(&req->iomgr_obj, name);
   req->host = gpr_strdup(request->host);
+  req->ssl_host_override = gpr_strdup(request->ssl_host_override);
 
   grpc_pollset_set_add_pollset(exec_ctx, &req->context->pollset_set,
                                req->pollset);
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index 6469c2f03e7e9d7c677b15d1d805b98c66fd2c70..30875d71f13b7767f325e1d25ea39d0e7593a266 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.h
@@ -74,6 +74,8 @@ extern const grpc_httpcli_handshaker grpc_httpcli_ssl;
 typedef struct grpc_httpcli_request {
   /* The host name to connect to */
   char *host;
+  /* The host to verify in the SSL handshake (or NULL) */
+  char *ssl_host_override;
   /* The path of the resource to fetch */
   char *path;
   /* Additional headers: count and key/values; the following are supplied
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index 4012f995c7b0c8bc47d619e32c315d0428d82384..d47774251a9086a8ecb72617be04a86112e61a4d 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -69,13 +69,13 @@ static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
   gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
 }
 
-static void test_get(int use_ssl, int port) {
+static void test_get(int port) {
   grpc_httpcli_request req;
   char *host;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   g_done = 0;
-  gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_get", use_ssl);
+  gpr_log(GPR_INFO, "test_get");
 
   gpr_asprintf(&host, "localhost:%d", port);
   gpr_log(GPR_INFO, "requesting from %s", host);
@@ -83,7 +83,7 @@ static void test_get(int use_ssl, int port) {
   memset(&req, 0, sizeof(req));
   req.host = host;
   req.path = "/get";
-  req.handshaker = use_ssl ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+  req.handshaker = &grpc_httpcli_plaintext;
 
   grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
                    on_finish, (void *)42);
@@ -100,13 +100,13 @@ static void test_get(int use_ssl, int port) {
   gpr_free(host);
 }
 
-static void test_post(int use_ssl, int port) {
+static void test_post(int port) {
   grpc_httpcli_request req;
   char *host;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   g_done = 0;
-  gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_post", (int)use_ssl);
+  gpr_log(GPR_INFO, "test_post");
 
   gpr_asprintf(&host, "localhost:%d", port);
   gpr_log(GPR_INFO, "posting to %s", host);
@@ -114,7 +114,7 @@ static void test_post(int use_ssl, int port) {
   memset(&req, 0, sizeof(req));
   req.host = host;
   req.path = "/post";
-  req.handshaker = use_ssl ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+  req.handshaker = &grpc_httpcli_plaintext;
 
   grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
                     n_seconds_time(15), on_finish, (void *)42);
@@ -170,8 +170,8 @@ int main(int argc, char **argv) {
   grpc_httpcli_context_init(&g_context);
   grpc_pollset_init(&g_pollset);
 
-  test_get(0, port);
-  test_post(0, port);
+  test_get(port);
+  test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
   grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
diff --git a/test/core/httpcli/httpscli_test.c b/test/core/httpcli/httpscli_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..b1c1913cae0d6c8393d59a45529c206b9d4f806a
--- /dev/null
+++ b/test/core/httpcli/httpscli_test.c
@@ -0,0 +1,188 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "src/core/httpcli/httpcli.h"
+
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include "src/core/iomgr/iomgr.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/subprocess.h>
+#include <grpc/support/sync.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static int g_done = 0;
+static grpc_httpcli_context g_context;
+static grpc_pollset g_pollset;
+
+static gpr_timespec n_seconds_time(int seconds) {
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
+}
+
+static void on_finish(grpc_exec_ctx *exec_ctx, void *arg,
+                      const grpc_httpcli_response *response) {
+  const char *expect =
+      "<html><head><title>Hello world!</title></head>"
+      "<body><p>This is a test</p></body></html>";
+  GPR_ASSERT(arg == (void *)42);
+  GPR_ASSERT(response);
+  GPR_ASSERT(response->status == 200);
+  GPR_ASSERT(response->body_length == strlen(expect));
+  GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
+  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  g_done = 1;
+  grpc_pollset_kick(&g_pollset, NULL);
+  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+}
+
+static void test_get(int port) {
+  grpc_httpcli_request req;
+  char *host;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+  g_done = 0;
+  gpr_log(GPR_INFO, "test_get");
+
+  gpr_asprintf(&host, "localhost:%d", port);
+  gpr_log(GPR_INFO, "requesting from %s", host);
+
+  memset(&req, 0, sizeof(req));
+  req.host = host;
+  req.ssl_host_override = "foo.test.google.fr";
+  req.path = "/get";
+  req.handshaker = &grpc_httpcli_ssl;
+
+  grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
+                   on_finish, (void *)42);
+  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  while (!g_done) {
+    grpc_pollset_worker worker;
+    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+                      gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
+    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    grpc_exec_ctx_finish(&exec_ctx);
+    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  }
+  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_free(host);
+}
+
+static void test_post(int port) {
+  grpc_httpcli_request req;
+  char *host;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+  g_done = 0;
+  gpr_log(GPR_INFO, "test_post");
+
+  gpr_asprintf(&host, "localhost:%d", port);
+  gpr_log(GPR_INFO, "posting to %s", host);
+
+  memset(&req, 0, sizeof(req));
+  req.host = host;
+  req.ssl_host_override = "foo.test.google.fr";
+  req.path = "/post";
+  req.handshaker = &grpc_httpcli_ssl;
+
+  grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
+                    n_seconds_time(15), on_finish, (void *)42);
+  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  while (!g_done) {
+    grpc_pollset_worker worker;
+    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+                      gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
+    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    grpc_exec_ctx_finish(&exec_ctx);
+    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  }
+  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_free(host);
+}
+
+static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, int success) {
+  grpc_pollset_destroy(p);
+}
+
+int main(int argc, char **argv) {
+  grpc_closure destroyed;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  gpr_subprocess *server;
+  char *me = argv[0];
+  char *lslash = strrchr(me, '/');
+  char *args[5];
+  char root[1024];
+  int port = grpc_pick_unused_port_or_die();
+
+  /* figure out where we are */
+  if (lslash) {
+    memcpy(root, me, (size_t)(lslash - me));
+    root[lslash - me] = 0;
+  } else {
+    strcpy(root, ".");
+  }
+
+  /* start the server */
+  gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
+  args[1] = "--port";
+  gpr_asprintf(&args[2], "%d", port);
+  args[3] = "--ssl";
+  server = gpr_subprocess_create(4, (const char **)args);
+  GPR_ASSERT(server);
+  gpr_free(args[0]);
+  gpr_free(args[2]);
+
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                               gpr_time_from_seconds(5, GPR_TIMESPAN)));
+
+  grpc_test_init(argc, argv);
+  grpc_init();
+  grpc_httpcli_context_init(&g_context);
+  grpc_pollset_init(&g_pollset);
+
+  test_get(port);
+  test_post(port);
+
+  grpc_httpcli_context_destroy(&g_context);
+  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_shutdown();
+
+  gpr_subprocess_destroy(server);
+
+  return 0;
+}
diff --git a/test/core/httpcli/test_server.py b/test/core/httpcli/test_server.py
index 4aaf5e30f8dbfbc9e61edff003284045e65d2279..225c2a6b0fcb0183e50f47a26f273721f8ef48f3 100755
--- a/test/core/httpcli/test_server.py
+++ b/test/core/httpcli/test_server.py
@@ -4,9 +4,18 @@
 
 import argparse
 import BaseHTTPServer
+import os
+import ssl
+import sys
+
+_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem'))
+_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key'))
+print _PEM
+open(_PEM).close()
 
 argp = argparse.ArgumentParser(description='Server for httpcli_test')
 argp.add_argument('-p', '--port', default=10080, type=int)
+argp.add_argument('-s', '--ssl', default=False, action='store_true')
 args = argp.parse_args()
 
 print 'server running on port %d' % args.port
@@ -28,4 +37,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
 		if self.path == '/post' and content == 'hello':
 			self.good()
 
-BaseHTTPServer.HTTPServer(('', args.port), Handler).serve_forever()
+httpd = BaseHTTPServer.HTTPServer(('localhost', args.port), Handler)
+if args.ssl:
+	httpd.socket = ssl.wrap_socket(httpd.socket, certfile=_PEM, keyfile=_KEY, server_side=True)
+httpd.serve_forever()
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index e3df912480389b105eaaef8e4c53f25e0125df6c..006f4bcdf1f4bd2d3872165dd48ef6a60afc3add 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -152,7 +152,10 @@ class CLanguage(object):
       else:
         binary = 'bins/%s/%s' % (config.build_config, target['name'])
       if os.path.isfile(binary):
-        out.append(config.job_spec([binary], [binary]))
+        out.append(config.job_spec([binary], [binary],
+                                   environ={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
+                                            os.path.abspath(os.path.dirname(
+                                                sys.argv[0]) + '/../../src/core/tsi/test_creds/ca.pem')}))
       elif args.regex == '.*' or platform_string() == 'windows':
         print '\nWARNING: binary not found, skipping', binary
     return sorted(out)
@@ -192,6 +195,7 @@ class CLanguage(object):
   def __str__(self):
     return self.make_target
 
+
 class NodeLanguage(object):
 
   def test_specs(self, config, args):
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index af94a1a38d25fca27753dae0c7f4f01d945f6b91..8822126099e4ef7697ccf2f8e3f1b570cbda8ae3 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -742,6 +742,20 @@
       "test/core/httpcli/httpcli_test.c"
     ]
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "httpscli_test", 
+    "src": [
+      "test/core/httpcli/httpscli_test.c"
+    ]
+  }, 
   {
     "deps": [
       "gpr", 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 6ec1955cff3f6faee60c07c7ef7260e8ba86353b..94be72b4a26209982df1710c7231aec62afb65e4 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -851,6 +851,18 @@
       "posix"
     ]
   }, 
+  {
+    "ci_platforms": [
+      "linux"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "httpscli_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "ci_platforms": [
       "linux",