diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index 8f3249407a766a25b992cd15abb9188c66daa800..563f0265b22734c677ba703653e52dcd1a0f38a3 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -592,7 +592,8 @@ static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer(
 // alt ref frames tend to be coded at a higher than ambient quality
 static INLINE int frame_is_boosted(const VP9_COMP *cpi) {
   return frame_is_intra_only(&cpi->common) || cpi->refresh_alt_ref_frame ||
-         (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref);
+         (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref) ||
+         vp9_is_upper_layer_key_frame(cpi);
 }
 
 static INLINE int get_token_alloc(int mb_rows, int mb_cols) {
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 3d4b9625901a95d536524ad443c7490b06d93b8c..a9430232b4ed8db2ddf24ca0834355e9b3b3ae19 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1727,8 +1727,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
       twopass->gf_bits = gf_bits;
     }
     if (i == 1 ||
-        (!rc->source_alt_ref_pending &&
-         cpi->common.frame_type != KEY_FRAME)) {
+        (!rc->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME &&
+         !vp9_is_upper_layer_key_frame(cpi))) {
       // Calculate the per frame bit target for this frame.
       vp9_rc_set_frame_target(cpi, gf_bits);
     }
@@ -2290,11 +2290,16 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
     this_frame_copy = this_frame;
     find_next_key_frame(cpi, &this_frame_copy);
     // Don't place key frame in any enhancement layers in spatial svc
-    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 &&
-        cpi->svc.spatial_layer_id > 0) {
-      cm->frame_type = INTER_FRAME;
+    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
+      lc->is_key_frame = 1;
+      if (cpi->svc.spatial_layer_id > 0) {
+        cm->frame_type = INTER_FRAME;
+      }
     }
   } else {
+    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
+      lc->is_key_frame = 0;
+    }
     cm->frame_type = INTER_FRAME;
   }
 
@@ -2392,9 +2397,11 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
   cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
 
 #ifdef LONG_TERM_VBR_CORRECTION
-  if (cpi->common.frame_type != KEY_FRAME) {
+  if (cpi->common.frame_type != KEY_FRAME &&
+      !vp9_is_upper_layer_key_frame(cpi)) {
 #else
-  if (cpi->common.frame_type == KEY_FRAME) {
+  if (cpi->common.frame_type == KEY_FRAME ||
+      vp9_is_upper_layer_key_frame(cpi)) {
     // For key frames kf_group_bits already had the target bits subtracted out.
     // So now update to the correct value based on the actual bits used.
     cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - bits_used;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 6ebd9f3fa4f7e88b23794a1253d85d49d9c29b99..b123bfdcbb42fac3dedf67b43329e0eedbc0cc79 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -807,7 +807,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
   int active_worst_quality = cpi->twopass.active_worst_quality;
   int q;
 
-  if (frame_is_intra_only(cm)) {
+  if (frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) {
 #if !CONFIG_MULTIPLE_ARF
     // Handle the special case for key frames forced when we have75 reached
     // the maximum key frame interval. Here force the Q to a range
@@ -928,7 +928,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
     vp9_clear_system_state();
 
     // Limit Q range for the adaptive loop.
-    if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) {
+    if ((cm->frame_type == KEY_FRAME || vp9_is_upper_layer_key_frame(cpi)) &&
+        !rc->this_key_frame_forced) {
       qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
                                           active_worst_quality, 2.0);
     } else if (!rc->is_src_frame_alt_ref &&
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index 2379f35b518c8b816d89f77325135d525d3ba25f..5342447d67ea28120b8b8cd7a557fe69b3222ace 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -220,3 +220,16 @@ void vp9_inc_frame_in_layer(SVC *svc) {
       : &svc->layer_context[svc->spatial_layer_id];
   ++lc->current_video_frame_in_layer;
 }
+
+int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi) {
+  int is_upper_layer_key_frame = 0;
+
+  if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 &&
+      cpi->svc.spatial_layer_id > 0) {
+    if (cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame) {
+      is_upper_layer_key_frame = 1;
+    }
+  }
+
+  return is_upper_layer_key_frame;
+}
diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h
index 2abed3055cb6c41cdb8458be073e77a3db4791be..74d9c1c0d426bce75d6caef60e6df65dcbf31dcf 100644
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -30,6 +30,7 @@ typedef struct {
   struct twopass_rc twopass;
   struct vpx_fixed_buf rc_twopass_stats_in;
   unsigned int current_video_frame_in_layer;
+  int is_key_frame;
 } LAYER_CONTEXT;
 
 typedef struct {
@@ -73,6 +74,9 @@ void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi);
 // Increment number of video frames in layer
 void vp9_inc_frame_in_layer(SVC *svc);
 
+// Check if current layer is key frame in spatial upper layer
+int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif