diff --git a/lib/private/legacy/preferences.php b/lib/private/legacy/preferences.php
index 71d0b749f43f7d3734ff07fecf8eec52fde62fb3..060274085feb67179649aff9929774fc53df9684 100644
--- a/lib/private/legacy/preferences.php
+++ b/lib/private/legacy/preferences.php
@@ -84,14 +84,14 @@ class OC_Preferences{
 	 * @param string $app app
 	 * @param string $key key
 	 * @param string $value value
-	 * @return bool
+	 * @param string $preCondition only set value if the key had a specific value before
+	 * @return bool true if value was set, otherwise false
 	 *
 	 * Adds a value to the preferences. If the key did not exist before, it
 	 * will be added automagically.
 	 */
-	public static function setValue( $user, $app, $key, $value ) {
-		self::$object->setValue( $user, $app, $key, $value );
-		return true;
+	public static function setValue( $user, $app, $key, $value, $preCondition = null ) {
+		return self::$object->setValue( $user, $app, $key, $value, $preCondition );
 	}
 
 	/**
diff --git a/lib/private/preferences.php b/lib/private/preferences.php
index 0dc5b26810ad996dc3fc27589d2e4afce820fa71..d1db25bbf09c8be74b4cd7692d62b45e50df19d2 100644
--- a/lib/private/preferences.php
+++ b/lib/private/preferences.php
@@ -165,44 +165,56 @@ class Preferences {
 	 * @param string $app app
 	 * @param string $key key
 	 * @param string $value value
+	 * @param string $preCondition only set value if the key had a specific value before
+	 * @return bool true if value was set, otherwise false
 	 *
 	 * Adds a value to the preferences. If the key did not exist before, it
 	 * will be added automagically.
 	 */
-	public function setValue($user, $app, $key, $value) {
+	public function setValue($user, $app, $key, $value, $preCondition = null) {
 		// Check if the key does exist
 		$query = 'SELECT COUNT(*) FROM `*PREFIX*preferences`'
 			. ' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
 		$count = $this->conn->fetchColumn($query, array($user, $app, $key));
 		$exists = $count > 0;
 
-		if (!$exists) {
+		$affectedRows = 0;
+
+		if (!$exists && $preCondition === null) {
 			$data = array(
 				'userid' => $user,
 				'appid' => $app,
 				'configkey' => $key,
 				'configvalue' => $value,
 			);
-			$this->conn->insert('*PREFIX*preferences', $data);
-		} else {
-			$data = array(
-				'configvalue' => $value,
-			);
-			$where = array(
-				'userid' => $user,
-				'appid' => $app,
-				'configkey' => $key,
-			);
-			$this->conn->update('*PREFIX*preferences', $data, $where);
+			$affectedRows = $this->conn->insert('*PREFIX*preferences', $data);
+		} elseif ($exists) {
+			$data = array($value, $user, $app, $key);
+			$sql  = "UPDATE `*PREFIX*preferences` SET `configvalue` = ?"
+					. " WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?";
+
+			if ($preCondition !== null) {
+				if (\OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') {
+					//oracle hack: need to explicitly cast CLOB to CHAR for comparison
+					$sql .= " AND to_char(`configvalue`) = ?";
+				} else {
+					$sql .= " AND `configvalue` = ?";
+				}
+				$data[] = $preCondition;
+			}
+			$affectedRows = $this->conn->executeUpdate($sql, $data);
 		}
 
 		// only add to the cache if we already loaded data for the user
-		if (isset($this->cache[$user])) {
+		if ($affectedRows > 0 && isset($this->cache[$user])) {
 			if (!isset($this->cache[$user][$app])) {
 				$this->cache[$user][$app] = array();
 			}
 			$this->cache[$user][$app][$key] = $value;
 		}
+
+		return ($affectedRows > 0) ? true : false;
+
 	}
 
 	/**
diff --git a/tests/lib/preferences.php b/tests/lib/preferences.php
index 93c9704f6c6de004e7e45c4800f3dcf22a217d8f..d31b0257bad7f59df5a6ed220f690cd0e789db39 100644
--- a/tests/lib/preferences.php
+++ b/tests/lib/preferences.php
@@ -97,6 +97,42 @@ class Test_Preferences extends PHPUnit_Framework_TestCase {
 		$this->assertEquals('othervalue', $value);
 	}
 
+	public function testSetValueWithPreCondition() {
+		// remove existing key
+		$this->assertTrue(\OC_Preferences::deleteKey('Someuser', 'setvalueapp', 'newkey'));
+
+		// add new preference with pre-condition should fails
+		$this->assertFalse(\OC_Preferences::setValue('Someuser', 'setvalueapp', 'newkey', 'newvalue', 'preCondition'));
+		$query = \OC_DB::prepare('SELECT `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?');
+		$result = $query->execute(array('Someuser', 'setvalueapp', 'newkey'));
+		$row = $result->fetchRow();
+		$this->assertFalse($row);
+
+		// add new preference without pre-condition should insert the new value
+		$this->assertTrue(\OC_Preferences::setValue('Someuser', 'setvalueapp', 'newkey', 'newvalue'));
+		$query = \OC_DB::prepare('SELECT `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?');
+		$result = $query->execute(array('Someuser', 'setvalueapp', 'newkey'));
+		$row = $result->fetchRow();
+		$value = $row['configvalue'];
+		$this->assertEquals('newvalue', $value);
+
+		// wrong pre-condition, value should stay the same
+		$this->assertFalse(\OC_Preferences::setValue('Someuser', 'setvalueapp', 'newkey', 'othervalue', 'preCondition'));
+		$query = \OC_DB::prepare('SELECT `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?');
+		$result = $query->execute(array('Someuser', 'setvalueapp', 'newkey'));
+		$row = $result->fetchRow();
+		$value = $row['configvalue'];
+		$this->assertEquals('newvalue', $value);
+
+		// correct pre-condition, value should change
+		$this->assertTrue(\OC_Preferences::setValue('Someuser', 'setvalueapp', 'newkey', 'othervalue', 'newvalue'));
+		$query = \OC_DB::prepare('SELECT `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?');
+		$result = $query->execute(array('Someuser', 'setvalueapp', 'newkey'));
+		$row = $result->fetchRow();
+		$value = $row['configvalue'];
+		$this->assertEquals('othervalue', $value);
+	}
+
 	public function testDeleteKey() {
 		$this->assertTrue(\OC_Preferences::deleteKey('Deleteuser', 'deleteapp', 'deletekey'));
 		$query = \OC_DB::prepare('SELECT `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?');
@@ -165,19 +201,11 @@ class Test_Preferences_Object extends PHPUnit_Framework_TestCase {
 					)
 				));
 		$connectionMock->expects($this->once())
-			->method('update')
-			->with($this->equalTo('*PREFIX*preferences'),
-				$this->equalTo(
-					array(
-						'configvalue' => 'v2',
-					)),
-				$this->equalTo(
-					array(
-						'userid' => 'grg',
-						'appid' => 'bar',
-						'configkey' => 'foo',
-					)
-				));
+			->method('executeUpdate')
+			->with($this->equalTo("UPDATE `*PREFIX*preferences` SET `configvalue` = ?"
+						. " WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?"),
+				$this->equalTo(array('v2', 'grg', 'bar', 'foo'))
+				);
 
 		$preferences = new OC\Preferences($connectionMock);
 		$preferences->setValue('grg', 'bar', 'foo', 'v1');