diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index c5bb7c490e2dced8214778406d8f8ca206cb4ad2..43b3199d92c0369b9c44f36ebe159584f2193b26 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -388,6 +388,103 @@ function timeoutOnSleepingServer($stub)
              'Call status was not DEADLINE_EXCEEDED');
 }
 
+function customMetadata($stub)
+{
+    $ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
+    $ECHO_INITIAL_VALUE = 'test_initial_metadata_value';
+    $ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
+    $ECHO_TRAILING_VALUE = 'ababab';
+    $request_len = 271828;
+    $response_len = 314159;
+
+    $request = new grpc\testing\SimpleRequest();
+    $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE);
+    $request->setResponseSize($response_len);
+    $payload = new grpc\testing\Payload();
+    $payload->setType(grpc\testing\PayloadType::COMPRESSABLE);
+    $payload->setBody(str_repeat("\0", $request_len));
+    $request->setPayload($payload);
+
+    $metadata = [
+        $ECHO_INITIAL_KEY => [$ECHO_INITIAL_VALUE],
+        $ECHO_TRAILING_KEY => [$ECHO_TRAILING_VALUE],
+    ];
+    $call = $stub->UnaryCall($request, $metadata);
+
+    $initial_metadata = $call->getMetadata();
+    hardAssert(array_key_exists($ECHO_INITIAL_KEY, $initial_metadata),
+               'Initial metadata does not contain expected key');
+    hardAssert($initial_metadata[$ECHO_INITIAL_KEY][0] ==
+               $ECHO_INITIAL_VALUE,
+               'Incorrect initial metadata value');
+
+    list($result, $status) = $call->wait();
+    hardAssert($status->code === Grpc\STATUS_OK,
+               'Call did not complete successfully');
+
+    $trailing_metadata = $call->getTrailingMetadata();
+    hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata),
+               'Trailing metadata does not contain expected key');
+    hardAssert($trailing_metadata[$ECHO_TRAILING_KEY][0] ==
+               $ECHO_TRAILING_VALUE, 'Incorrect trailing metadata value');
+
+    $streaming_call = $stub->FullDuplexCall($metadata);
+
+    $streaming_request = new grpc\testing\StreamingOutputCallRequest();
+    $streaming_request->setPayload($payload);
+    $streaming_call->write($streaming_request);
+    $streaming_call->writesDone();
+
+    hardAssert($streaming_call->getStatus()->code === Grpc\STATUS_OK,
+               'Call did not complete successfully');
+
+    $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
+    hardAssert(array_key_exists($ECHO_TRAILING_KEY,
+                                $streaming_trailing_metadata),
+               'Trailing metadata does not contain expected key');
+    hardAssert($streaming_trailing_metadata[$ECHO_TRAILING_KEY][0] ==
+               $ECHO_TRAILING_VALUE, 'Incorrect trailing metadata value');
+}
+
+function statusCodeAndMessage($stub)
+{
+    $echo_status = new grpc\testing\EchoStatus();
+    $echo_status->setCode(2);
+    $echo_status->setMessage("test status message");
+
+    $request = new grpc\testing\SimpleRequest();
+    $request->setResponseStatus($echo_status);
+
+    $call = $stub->UnaryCall($request);
+    list($result, $status) = $call->wait();
+
+    hardAssert($status->code === 2,
+               'Received unexpected status code');
+    hardAssert($status->details === "test status message",
+               'Received unexpected status details');
+
+    $streaming_call = $stub->FullDuplexCall();
+
+    $streaming_request = new grpc\testing\StreamingOutputCallRequest();
+    $streaming_request->setResponseStatus($echo_status);
+    $streaming_call->write($streaming_request);
+    $streaming_call->writesDone();
+
+    $status = $streaming_call->getStatus();
+    hardAssert($status->code === 2,
+               'Received unexpected status code');
+    hardAssert($status->details === "test status message",
+               'Received unexpected status details');
+}
+
+function unimplementedMethod($stub)
+{
+    $call = $stub->UnimplementedCall(new grpc\testing\EmptyMessage());
+    list($result, $status) = $call->wait();
+    hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
+               'Received unexpected status code');
+}
+
 function _makeStub($args)
 {
     if (!array_key_exists('server_host', $args)) {
@@ -472,7 +569,11 @@ function _makeStub($args)
         $opts['update_metadata'] = $update_metadata;
     }
 
-    $stub = new grpc\testing\TestServiceClient($server_address, $opts);
+    if ($test_case == 'unimplemented_method') {
+      $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts);
+    } else {
+      $stub = new grpc\testing\TestServiceClient($server_address, $opts);
+    }
 
     return $stub;
 }
@@ -514,6 +615,15 @@ function interop_main($args, $stub = false)
         case 'timeout_on_sleeping_server':
             timeoutOnSleepingServer($stub);
             break;
+        case 'custom_metadata':
+            customMetadata($stub);
+            break;
+        case 'status_code_and_message':
+            statusCodeAndMessage($stub);
+            break;
+        case 'unimplemented_method':
+            unimplementedMethod($stub);
+            break;
         case 'service_account_creds':
             serviceAccountCreds($stub, $args);
             break;
diff --git a/src/php/tests/interop/messages.proto b/src/php/tests/interop/messages.proto
index de0b1a232051052e2117f3718f21f040df06150c..44e3c3b8f9726cb3efd85ab2407be3bbb8a93d36 100644
--- a/src/php/tests/interop/messages.proto
+++ b/src/php/tests/interop/messages.proto
@@ -1,5 +1,5 @@
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -41,9 +41,6 @@ enum PayloadType {
 
   // Uncompressable binary format.
   UNCOMPRESSABLE = 1;
-
-  // Randomly chosen from all other formats defined in this enum.
-  RANDOM = 2;
 }
 
 // A block of data, to simply increase gRPC message size.
@@ -54,6 +51,13 @@ message Payload {
   optional bytes body = 2;
 }
 
+// A protobuf representation for grpc status. This is used by test
+// clients to specify a status that the server should attempt to return.
+message EchoStatus {
+  optional int32 code = 1;
+  optional string message = 2;
+}
+
 // Unary request.
 message SimpleRequest {
   // Desired payload type in the response from the server.
@@ -72,6 +76,12 @@ message SimpleRequest {
 
   // Whether SimpleResponse should include OAuth scope.
   optional bool fill_oauth_scope = 5;
+
+  // Whether to request the server to compress the response.
+  optional bool request_compressed_response = 6;
+
+  // Whether server should return a given status
+  optional EchoStatus response_status = 7;
 }
 
 // Unary response, as configured by the request.
@@ -123,6 +133,12 @@ message StreamingOutputCallRequest {
 
   // Optional input payload sent along with the request.
   optional Payload payload = 3;
+
+  // Whether to request the server to compress the response.
+  optional bool request_compressed_response = 6;
+
+  // Whether server should return a given status
+  optional EchoStatus response_status = 7;
 }
 
 // Server-streaming response, as configured by the request and parameters.
@@ -130,3 +146,17 @@ message StreamingOutputCallResponse {
   // Payload to increase response size.
   optional Payload payload = 1;
 }
+
+// For reconnect interop test only.
+// Client tells server what reconnection parameters it used.
+message ReconnectParams {
+  optional int32 max_reconnect_backoff_ms = 1;
+}
+
+// For reconnect interop test only.
+// Server tells client whether its reconnects are following the spec and the
+// reconnect backoffs it saw.
+message ReconnectInfo {
+  optional bool passed = 1;
+  repeated int32 backoff_ms = 2;
+}
diff --git a/src/php/tests/interop/test.proto b/src/php/tests/interop/test.proto
index 0d169e7f64082170b07007d03ca4a2b56ed7fe3f..57ef30ee1c113b0fde7e2a065e3523cc6544c629 100644
--- a/src/php/tests/interop/test.proto
+++ b/src/php/tests/interop/test.proto
@@ -1,5 +1,5 @@
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -69,3 +69,10 @@ service TestService {
   rpc HalfDuplexCall(stream StreamingOutputCallRequest)
       returns (stream StreamingOutputCallResponse);
 }
+
+// A simple service NOT implemented at servers so clients can test for
+// that case.
+service UnimplementedService {
+  // A call that no server should implement
+  rpc UnimplementedCall(grpc.testing.EmptyMessage) returns (grpc.testing.EmptyMessage);
+}
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 5aaefb1ae144dad5e7be99275671ca28d87b0657..0787637d75851976d6e7fbe4a6cbe38c6a4b9e66 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -252,7 +252,7 @@ class PHPLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def unimplemented_test_cases_server(self):
     return []