diff --git a/src/wp-includes/js/customize-base.js b/src/wp-includes/js/customize-base.js
index a1528de4f..53790909a 100644
--- a/src/wp-includes/js/customize-base.js
+++ b/src/wp-includes/js/customize-base.js
@@ -203,12 +203,14 @@ window.wp = window.wp || {};
 		 * Set the value and trigger all bound callbacks.
 		 *
 		 * @param {object} to New value.
+     * @param {object} set of optional arguments when setting the value
 		 */
-		set: function( to ) {
-			var from = this._value;
+		set: function( to, args ) {
+			var from = this._value, self = this;
 
 			to = this._setter.apply( this, arguments );
 			to = this.validate( to );
+      args = _.extend( { silent : false }, _.isObject( args ) ? args : {} );
 
 			// Bail if the sanitized value is null or unchanged.
 			if ( null === to || _.isEqual( from, to ) ) {
@@ -217,8 +219,16 @@ window.wp = window.wp || {};
 
 			this._value = to;
 			this._dirty = true;
+      if ( args.silent ) {
+        return this;
+      }
 
 			this.callbacks.fireWith( this, [ to, from ] );
+      if ( this.topics ) {
+        _.each( self.topics, function( _cbs ){
+            _cbs.fireWith( self, [ to, from ] );
+        });
+      }
 
 			return this;
 		},
@@ -246,25 +256,71 @@ window.wp = window.wp || {};
 			return value;
 		},
 
+    /**
+     * Trigger the bound callbacks of a specific topic, or trigger the anonymous callbacks
+     *
+     * @param {string} the topic id
+     * @param {to} the optional new value
+     * @param {from} the optional previous value
+     */
+    trigger: function( id, to, from ) {
+      to = to || this();
+      from = from || this();
+      if ( this.topics && this.topics[ id ] ) {
+        this.topics[ id ].fireWith( this, [ to, from ] );
+      } else {
+        this.callbacks.fireWith( this, [ to, from ] );
+      }
+      return this;
+    },
+
 		/**
-		 * Bind a function to be invoked whenever the value changes.
-		 *
-		 * @param {...Function} A function, or multiple functions, to add to the callback stack.
-		 */
-		bind: function() {
-			this.callbacks.add.apply( this.callbacks, arguments );
-			return this;
-		},
+     * Bind a function to be invoked whenever the value changes.
+     * @param {string} the optional id of the callbacks topic
+     * @param {...Function} A function, or multiple functions, to add to the callback stack.
+     */
+    bind: function( id ) {
+      if ( _.isFunction( id ) ) {
+        this.callbacks.add.apply( this.callbacks, arguments );
+      } else {
+        this.topics = this.topics || {};
+        this.topics[ id ] = this.topics[ id ] || $.Callbacks();
+        this.topics[ id ].add.apply( this.topics[ id ], slice.call( arguments, 1 ) );
+      }
+      return this;
+    },
 
 		/**
-		 * Unbind a previously bound function.
-		 *
-		 * @param {...Function} A function, or multiple functions, to remove from the callback stack.
-		 */
-		unbind: function() {
-			this.callbacks.remove.apply( this.callbacks, arguments );
-			return this;
-		},
+     * Unbind a previously bound function.
+     *
+     * @param {string} the optional id of the callbacks topic
+     * @param {...Function} A function, or multiple functions, to remove from the callback stack.
+     */
+    unbind: function( id ) {
+      if ( _.isFunction( id ) ) {
+        this.callbacks.remove.apply( this.callbacks, arguments );
+      } else if ( this.topics && this.topics[ id ] ) {
+        this.topics[ id ].remove.apply( this.topics[ id ], slice.call( arguments, 1 ) );
+      }
+      return this;
+    },
+
+    /**
+     * Unbind all previously bound function of a callbacks topic if specified
+     * Or unbind all functions if no topic is specified
+     *
+     * @param {string} optional topic id
+     */
+    unbindAll: function( id ) {
+      if ( this.topics && this.topics[ id ] ) {
+        this.topics[ id ] = $.Callbacks();
+      } else if ( this.topics ) {
+        this.topics = {};
+      } else {
+        this.callbacks = $.Callbacks();
+      }
+      return this;
+    },
 
 		link: function() { // values*
 			var set = this.set;
