diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index bdded628db61d120cc873710d26dfab15af1ea0c..bab0d6f0ae7b83833bdff08e630054dc8f22a951 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -378,6 +378,14 @@ const options = [
     env: false,
   },
   // Version behaviour
+  {
+    name: 'allowedVersions',
+    description: 'A semver range defining allowed versions for dependencies',
+    type: 'string',
+    stage: 'package',
+    cli: false,
+    env: false,
+  },
   {
     name: 'pinDigests',
     description: 'Whether to add digests to Dockerfile source images',
diff --git a/lib/config/validation.js b/lib/config/validation.js
index 836fbd0ef43b15368f6713ccbdaa7f0bf9a32b03..e0fe44d25eb23575bb8ce7c91f109e4e4f6bca3a 100644
--- a/lib/config/validation.js
+++ b/lib/config/validation.js
@@ -1,3 +1,4 @@
+const semver = require('semver');
 const options = require('./definitions').getOptions();
 const { hasValidSchedule } = require('../workers/branch/schedule');
 
@@ -60,6 +61,13 @@ function validateConfig(config) {
             message: `Invalid schedule: \`${errorMessage}\``,
           });
         }
+      } else if (key === 'allowedVersions' && val !== null) {
+        if (!semver.validRange(val)) {
+          errors.push({
+            depName: 'Configuration Error',
+            message: `Invalid semver range for allowedVersions: \`${val}\``,
+          });
+        }
       } else if (val != null) {
         const type = optionTypes[key];
         if (type === 'boolean') {
diff --git a/lib/workers/package/versions.js b/lib/workers/package/versions.js
index 4ee23863881c1f34201b9e0919920153516515d1..83b5d32b4821bcdfb1df25935f04ea077fd0be5b 100644
--- a/lib/workers/package/versions.js
+++ b/lib/workers/package/versions.js
@@ -18,7 +18,12 @@ function determineUpgrades(npmDep, config) {
   const result = {
     type: 'warning',
   };
-  const { currentVersion, lockedVersion, pinVersions } = config;
+  const {
+    currentVersion,
+    lockedVersion,
+    pinVersions,
+    allowedVersions,
+  } = config;
   const { versions } = npmDep;
   if (!versions || Object.keys(versions).length === 0) {
     result.message = `No versions returned from registry for this package`;
@@ -82,6 +87,10 @@ function determineUpgrades(npmDep, config) {
   _(versionList)
     // Filter out older versions as we can't upgrade to those
     .filter(version => semver.gt(version, changeLogFromVersion))
+    // fillter out non-allowed versions if preference is set
+    .reject(
+      version => allowedVersions && !semver.satisfies(version, allowedVersions)
+    )
     // Ignore unstable versions, unless the current version is unstable
     .reject(
       version =>
diff --git a/test/config/__snapshots__/validation.spec.js.snap b/test/config/__snapshots__/validation.spec.js.snap
index 63af4b2400174b152853531fc5bfbdace882a2ad..fcc172e25b9edcca991af685377806a2409c0a88 100644
--- a/test/config/__snapshots__/validation.spec.js.snap
+++ b/test/config/__snapshots__/validation.spec.js.snap
@@ -2,6 +2,10 @@
 
 exports[`config/validation validateConfig(config) errors for all types 1`] = `
 Array [
+  Object {
+    "depName": "Configuration Error",
+    "message": "Invalid semver range for allowedVersions: \`foo\`",
+  },
   Object {
     "depName": "Configuration Error",
     "message": "Configuration option \`enabled\` should be boolean. Found: 1 (number)",
diff --git a/test/config/validation.spec.js b/test/config/validation.spec.js
index 213386278a2f4dcbbc2698680c6cd2e133be3d98..3c2f725da2b687d58c8fcb5b015c5d4a299b6baf 100644
--- a/test/config/validation.spec.js
+++ b/test/config/validation.spec.js
@@ -18,6 +18,7 @@ describe('config/validation', () => {
     });
     it('errors for all types', () => {
       const config = {
+        allowedVersions: 'foo',
         enabled: 1,
         schedule: ['every 15 mins every weekday'],
         labels: 5,
@@ -31,7 +32,7 @@ describe('config/validation', () => {
       };
       const { warnings, errors } = configValidation.validateConfig(config);
       expect(warnings).toHaveLength(0);
-      expect(errors).toHaveLength(6);
+      expect(errors).toHaveLength(7);
       expect(errors).toMatchSnapshot();
     });
   });
diff --git a/website/docs/_posts/2017-10-05-configuration-options.md b/website/docs/_posts/2017-10-05-configuration-options.md
index a7b7e63aa4d0f2d68d1fe6b2988f86241edecfa9..834e5d68c65685bc2084d0ddfc9565be1f915979 100644
--- a/website/docs/_posts/2017-10-05-configuration-options.md
+++ b/website/docs/_posts/2017-10-05-configuration-options.md
@@ -14,6 +14,23 @@ Also, be sure to check out Renovate's [shareable config presets](/docs/configura
 
 If you have any questions about the below config options, or would like to get help/feedback about a config, please post it as an issue in [renovateapp/config-help](https://github.com/renovateapp/config-help) where it will be promptly answered.
 
+## allowedVersions
+
+A semver range defining allowed versions for dependencies
+
+| name | value  |
+| ---- | ------ |
+| type | string |
+
+Use this - usually within a packageRule - to limit how far to upgrade a dependency. For example, if you wish to upgrade to angular v1.5 but not to `angular` v1.6 or higher, you could defined this to be `<= 1.5` or `< 1.6.0`:
+
+```
+  "packageRules": [{
+    "packageNames": ["angular"],
+    "allowedVersions": "<=1.5"
+  }]
+```
+
 ## assignees
 
 Assignees for Pull Requests