diff --git a/celt b/celt
index 7c328c2d7a9bb28b837d935658ec05bfd7746aa6..6f6e8b39842a7d175e89f47e4d37ad5de8143ad2 160000
--- a/celt
+++ b/celt
@@ -1 +1 @@
-Subproject commit 7c328c2d7a9bb28b837d935658ec05bfd7746aa6
+Subproject commit 6f6e8b39842a7d175e89f47e4d37ad5de8143ad2
diff --git a/src/opus.h b/src/opus.h
index a3aed13671165737465e0233a9b0c19ef6fc6947..f3704a5c5ed0a9a58fa652bce7ac3f1deda9af9b 100644
--- a/src/opus.h
+++ b/src/opus.h
@@ -125,6 +125,11 @@ extern "C" {
 #define OPUS_GET_VOICE_RATIO_REQUEST 19
 #define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __check_int_ptr(x)
 
+#define OPUS_SET_VBR_CONSTRAINT_REQUEST 20
+#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __check_int(x)
+#define OPUS_GET_VBR_CONSTRAINT_REQUEST 21
+#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __check_int_ptr(x)
+
 typedef struct OpusEncoder OpusEncoder;
 typedef struct OpusDecoder OpusDecoder;
 
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index ae36b8579bcc34b46c823b89c61a0a3d230924ee..89b39eb7cd1de3f8de444d8330fd516d1903c277 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -360,6 +360,7 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
             if (st->use_vbr)
             {
                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
+                celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint));
                 celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
                 nb_compr_bytes = max_data_bytes-1;
             } else {
@@ -616,6 +617,18 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
             *value = st->voice_ratio;
         }
         break;
+        case OPUS_SET_VBR_CONSTRAINT_REQUEST:
+        {
+            int value = va_arg(ap, int);
+            st->vbr_constraint = value;
+        }
+        break;
+        case OPUS_GET_VBR_CONSTRAINT_REQUEST:
+        {
+            int *value = va_arg(ap, int*);
+            *value = st->vbr_constraint;
+        }
+        break;
         default:
             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
             break;
diff --git a/src/opus_encoder.h b/src/opus_encoder.h
index ce721eb0116faa6c118bc9d577aaa8190bc9ff00..336b9a770323bd1040166b3ee9400ec935bbec67 100644
--- a/src/opus_encoder.h
+++ b/src/opus_encoder.h
@@ -51,6 +51,7 @@ struct OpusEncoder {
     /* Sampling rate (at the API level) */
     int          Fs;
     int          use_vbr;
+    int          vbr_constraint;
     int          bitrate_bps;
     int          encoder_buffer;
     int          delay_compensation;
diff --git a/src/test_opus.c b/src/test_opus.c
index ccbe6fa940cae8fea630e28059436113360595a3..dceed530a3fbba543eea0ecd07405d1e6a54b19c 100644
--- a/src/test_opus.c
+++ b/src/test_opus.c
@@ -82,6 +82,7 @@ int main(int argc, char *argv[])
    int complexity;
    int use_inbandfec;
    int use_dtx;
+   int cvbr = 0;
    int packet_loss_perc;
    int count=0, count_act=0, k;
    int skip;
@@ -169,6 +170,9 @@ int main(int argc, char *argv[])
         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandfec" ) == 0 ) {
             use_inbandfec = 1;
             args++;
+        } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) {
+            cvbr = 1;
+            args++;
         } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-dtx") == 0 ) {
             use_dtx = 1;
             args++;
@@ -222,6 +226,7 @@ int main(int argc, char *argv[])
    opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
    opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
    opus_encoder_ctl(enc, OPUS_SET_VBR_FLAG(use_vbr));
+   opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
    opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec));
    opus_encoder_ctl(enc, OPUS_SET_DTX_FLAG(use_dtx));