diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h
index fbb941969e95abb3441f77245c19bde2b31aca7b..cd1d47342f53ad4945440953b99713e573a544f7 100644
--- a/src/core/transport/chttp2/frame.h
+++ b/src/core/transport/chttp2/frame.h
@@ -54,6 +54,7 @@ typedef struct {
   gpr_uint8 process_ping_reply;
   gpr_uint8 goaway;
 
+  gpr_uint32 initial_window_update;
   gpr_uint32 window_update;
   gpr_uint32 goaway_last_stream_index;
   gpr_uint32 goaway_error;
diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c
index 8d3250c34ff0efb7228648455ee4ae397db8f1f6..9b9374e0fd8aeccc40b2865caef2ea4ac1fef8ae 100644
--- a/src/core/transport/chttp2/frame_settings.c
+++ b/src/core/transport/chttp2/frame_settings.c
@@ -218,6 +218,10 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
                 return GRPC_CHTTP2_CONNECTION_ERROR;
             }
           }
+          if (parser->id == 4 && parser->incoming_settings[parser->id] != parser->value) {
+            state->initial_window_update = parser->value - parser->incoming_settings[parser->id];
+            gpr_log(GPR_DEBUG, "adding %d for initial_window change", state->window_update);
+          }
           parser->incoming_settings[parser->id] = parser->value;
           if (grpc_http_trace) {
             gpr_log(GPR_DEBUG, "CHTTP2: got setting %d = %d", parser->id,
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 110a4b544f367613d549236b806ac8edac1c237d..fbd9d8a146bc2d3b882e1b14806d3623187f8d00 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -1485,6 +1485,18 @@ static int parse_frame_slice(transport *t, gpr_slice slice, int is_last) {
           }
         }
       }
+      if (st.initial_window_update) {
+        for (i = 0; i < t->stream_map.count; i++) {
+          stream *s = (stream*)(t->stream_map.values[i]);
+          /* TODO there are other scenarios */
+          if (s->outgoing_window == 0) {
+            s->outgoing_window += st.initial_window_update;
+            if (s->outgoing_sopb.nops) {
+                stream_list_join(t, s, WRITABLE);
+            }
+          }
+        }
+      }
       if (st.window_update) {
         if (t->incoming_stream_id) {
           /* if there was a stream id, this is for some stream */