diff --git a/docs/configuration.md b/docs/configuration.md
index 3fff9b9474bc37f1309a523db6c10faf65908241..c8d39f3f45d6e2f7c988645b53e6bf8d420866c1 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -328,26 +328,42 @@ Obviously, you can't set repository or package file location with this method.
   <td>`--ignore-deps`<td>
 </tr>
 <tr>
-  <td>`packages`</td>
-  <td>Package Rules</td>
+  <td>`packageRules`</td>
+  <td>Rules for matching package names</td>
   <td>list</td>
   <td><pre>[]</pre></td>
   <td></td>
   <td><td>
 </tr>
 <tr>
-  <td>`packageName`</td>
-  <td>A package name to match. Valid only within `packages` object</td>
-  <td>string</td>
-  <td><pre>null</pre></td>
+  <td>`packageNames`</td>
+  <td>Package names to match. Valid only within `packageRules` object</td>
+  <td>list</td>
+  <td><pre>[]</pre></td>
   <td></td>
   <td><td>
 </tr>
 <tr>
-  <td>`packagePattern`</td>
-  <td>A package name pattern to match. Valid only within `packages` object.</td>
-  <td>string</td>
-  <td><pre>null</pre></td>
+  <td>`excludePackageNames`</td>
+  <td>Package names to exclude. Valid only within `packageRules` object</td>
+  <td>list</td>
+  <td><pre>[]</pre></td>
+  <td></td>
+  <td><td>
+</tr>
+<tr>
+  <td>`packagePatterns`</td>
+  <td>Package name patterns to match. Valid only within `packageRules` object.</td>
+  <td>list</td>
+  <td><pre>[]</pre></td>
+  <td></td>
+  <td><td>
+</tr>
+<tr>
+  <td>`excludePackagePatterns`</td>
+  <td>Package name patterns to exclude. Valid only within `packageRules` object.</td>
+  <td>list</td>
+  <td><pre>[]</pre></td>
   <td></td>
   <td><td>
 </tr>
diff --git a/docs/faq.md b/docs/faq.md
index 80f2d3f862c2033d3e1d705f169ea74b587b8cc3..58533b9b58a3cb6ad1f37bf9c1c34156fa36be9d 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -73,7 +73,7 @@ To restrict `aws-sdk` to only weekly updates, you could add this package rule:
 ```
   "packages": [
     {
-      "packageName": "aws-sdk",
+      "packageNames": ["aws-sdk"],
       "schedule": ["after 9pm on sunday"]
     }
   ]
@@ -128,7 +128,7 @@ Set the configuration option `labels` to an array of labels to use
 
 1.  Add a `packages` array to your configuration.
 2.  Create one object inside this array
-3.  Set field `packageName` to value `"abc"`
+3.  Set field `packageNames` to value `["abc"]`
 4.  Add the configuration option to the same object.
 
 e.g.
@@ -136,7 +136,7 @@ e.g.
 ```
 "packages": [
   {
-    "packageName": "abc",
+    "packageNames": ["abc"],
     "assignees": ["importantreviewer"]
   }
 ]
@@ -144,12 +144,12 @@ e.g.
 
 ### Apply a rule, but only for packages starting with `abc`
 
-Do the same as above, but instead of using `packageName`, use `packagePattern` and a regex. e.g.
+Do the same as above, but instead of using `packageNames`, use `packagePatterns` and a regex. e.g.
 
 ```
 "packages": [
   {
-    "packagePattern": "^abc",
+    "packagePatterns": "^abc",
     "assignees": ["importantreviewer"]
   }
 ]
@@ -162,7 +162,7 @@ As above, but apply a `groupName`, e.g.
 ```
 "packages": [
   {
-    "packagePattern": "^abc",
+    "packagePatterns": "^abc",
     "groupName": ["abc packages"]
   }
 ]
diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 25bd51866ee4715e84806f5295f87dfcb51b5e15..3fdd14661fb5bc8deec575c152e24e17fc60d609 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -188,26 +188,45 @@ const options = [
     stage: 'depType',
   },
   {
-    name: 'packages',
-    description: 'Package Rules',
+    name: 'packageRules',
+    description: 'Rules for matching package names',
     type: 'list',
     stage: 'depType',
     cli: false,
     env: false,
   },
   {
-    name: 'packageName',
-    description: 'A package name to match. Valid only within `packages` object',
-    type: 'string',
+    name: 'packageNames',
+    description:
+      'Package names to match. Valid only within `packageRules` object',
+    type: 'list',
     stage: 'depType',
     cli: false,
     env: false,
   },
   {
-    name: 'packagePattern',
+    name: 'excludePackageNames',
     description:
-      'A package name pattern to match. Valid only within `packages` object.',
-    type: 'string',
+      'Package names to exclude. Valid only within `packageRules` object',
+    type: 'list',
+    stage: 'depType',
+    cli: false,
+    env: false,
+  },
+  {
+    name: 'packagePatterns',
+    description:
+      'Package name patterns to match. Valid only within `packageRules` object.',
+    type: 'list',
+    stage: 'depType',
+    cli: false,
+    env: false,
+  },
+  {
+    name: 'excludePackagePatterns',
+    description:
+      'Package name patterns to exclude. Valid only within `packageRules` object.',
+    type: 'list',
     stage: 'depType',
     cli: false,
     env: false,
diff --git a/lib/config/migration.js b/lib/config/migration.js
index 473a0fe75eadf86e485d181c970e4f3aa585f8f4..7dec6805d7ec566b31a1f73ab4892509197549dd 100644
--- a/lib/config/migration.js
+++ b/lib/config/migration.js
@@ -27,6 +27,18 @@ function migrateConfig(config) {
     } else if (key === 'schedule' && typeof val === 'string') {
       isMigrated = true;
       migratedConfig.schedule = [val];
+    } else if (key === 'packages') {
+      isMigrated = true;
+      migratedConfig.packageRules = migrateConfig(val);
+      delete migratedConfig.packages;
+    } else if (key === 'packageName') {
+      isMigrated = true;
+      migratedConfig.packageNames = [val];
+      delete migratedConfig.packageName;
+    } else if (key === 'packagePattern') {
+      isMigrated = true;
+      migratedConfig.packagePatterns = [val];
+      delete migratedConfig.packagePattern;
     } else if (key === 'depTypes' && Array.isArray(val)) {
       val.forEach(depType => {
         if (isObject(depType)) {
diff --git a/lib/workers/dep-type/index.js b/lib/workers/dep-type/index.js
index 746ba1c70e54ecaa2c2ba79789ee35d032b13e67..a4c6d454500c7177d0a2981e85576de356d21be5 100644
--- a/lib/workers/dep-type/index.js
+++ b/lib/workers/dep-type/index.js
@@ -57,20 +57,42 @@ async function renovateDepType(packageContent, config) {
 function getDepConfig(depTypeConfig, dep) {
   const depConfig = configParser.mergeChildConfig(depTypeConfig, dep);
   // Apply any matching package rules
-  if (depConfig.packages) {
+  if (depConfig.packageRules) {
     let packageRuleApplied = false;
-    depConfig.packages.forEach(packageConfig => {
+    depConfig.packageRules.forEach(packageRule => {
       // Apply at most 1 package fule
       if (!packageRuleApplied) {
-        const pattern =
-          packageConfig.packagePattern || `^${packageConfig.packageName}$`;
-        const packageRegex = new RegExp(pattern);
-        if (depConfig.depName.match(packageRegex)) {
+        if (
+          packageRule.packageNames &&
+          packageRule.packageNames.includes(depConfig.depName)
+        ) {
           packageRuleApplied = true;
+        } else if (packageRule.packagePatterns) {
+          for (const packagePattern of packageRule.packagePatterns) {
+            const packageRegex = new RegExp(packagePattern);
+            if (depConfig.depName.match(packageRegex)) {
+              packageRuleApplied = true;
+            }
+          }
+        }
+        if (
+          packageRule.excludePackageNames &&
+          packageRule.excludePackageNames.includes(depConfig.depName)
+        ) {
+          packageRuleApplied = false;
+        } else if (packageRule.excludePackagePatterns) {
+          for (const packagePattern of packageRule.excludePackagePatterns) {
+            const packageRegex = new RegExp(packagePattern);
+            if (depConfig.depName.match(packageRegex)) {
+              packageRuleApplied = false;
+            }
+          }
+        }
+        if (packageRuleApplied) {
           // Package rule config overrides any existing config
-          Object.assign(depConfig, packageConfig);
-          delete depConfig.packageName;
-          delete depConfig.packagePattern;
+          Object.assign(depConfig, packageRule);
+          delete depConfig.packageNames;
+          delete depConfig.packagePatterns;
         }
       }
     });
diff --git a/package.json b/package.json
index 1e555165ccc8781ca23fc4f398e129899ae4962e..3d7b8db5c43d591bd80440efe7173486f9a508cc 100644
--- a/package.json
+++ b/package.json
@@ -118,7 +118,7 @@
     "semanticCommits": true,
     "packages": [
       {
-        "packagePattern": "jest",
+        "packagePatterns": "jest",
         "groupName": "jest"
       }
     ]
diff --git a/test/config/__snapshots__/migration.spec.js.snap b/test/config/__snapshots__/migration.spec.js.snap
index e7eebe819404fab8a5fa65bfaedc67afd61b20b6..8c7d0c1a2f15bff54d0db66e57011311395ebbed 100644
--- a/test/config/__snapshots__/migration.spec.js.snap
+++ b/test/config/__snapshots__/migration.spec.js.snap
@@ -6,6 +6,20 @@ Object {
   "optionalDependencies": Object {
     "respectLatest": false,
   },
+  "packageRules": Object {
+    "isMigrated": true,
+    "migratedConfig": Object {
+      "0": Object {
+        "enabled": false,
+        "packageNames": Array [
+          "angular",
+        ],
+        "packagePatterns": Array [
+          "ang",
+        ],
+      },
+    },
+  },
   "schedule": Array [
     "after 5pm",
   ],
diff --git a/test/config/migration.spec.js b/test/config/migration.spec.js
index 5e3f8034f48b44ebf960d45a5a6cc2853cf85eaf..0632f6ce47140d504b648138795512348bf7f7d1 100644
--- a/test/config/migration.spec.js
+++ b/test/config/migration.spec.js
@@ -7,6 +7,13 @@ describe('config/migration', () => {
         enabled: true,
         maintainYarnLock: true,
         schedule: 'after 5pm',
+        packages: [
+          {
+            packageName: 'angular',
+            packagePattern: 'ang',
+            enabled: false,
+          },
+        ],
         depTypes: [
           'dependencies',
           {
diff --git a/test/config/validation.spec.js b/test/config/validation.spec.js
index a5ef8d43dbf163304a76be5f88e645ff88383cbc..8b51001ae4d31122daf307409200e6f0b00d3df9 100644
--- a/test/config/validation.spec.js
+++ b/test/config/validation.spec.js
@@ -23,7 +23,7 @@ describe('config/validation', () => {
         semanticPrefix: 7,
         githubAppId: 'none',
         lockFileMaintenance: false,
-        packages: [
+        packageRules: [
           {
             foo: 1,
           },
diff --git a/test/workers/dep-type/index.spec.js b/test/workers/dep-type/index.spec.js
index cb04b3b5133a75ed630fd1d884faeff4c50b3c14..325f41ef10424086e2178c224a2e9cfb138b9c0e 100644
--- a/test/workers/dep-type/index.spec.js
+++ b/test/workers/dep-type/index.spec.js
@@ -51,25 +51,36 @@ describe('lib/workers/dep-type/index', () => {
     const depTypeConfig = {
       foo: 'bar',
       logger,
-      packages: [
+      packageRules: [
         {
-          packageName: 'a',
+          packageNames: ['a', 'b'],
           x: 2,
         },
         {
-          packagePattern: 'a',
+          packagePatterns: ['a', 'b'],
+          excludePackageNames: ['aa'],
+          excludePackagePatterns: ['d'],
           y: 2,
         },
       ],
     };
-    it('applies only one rule', () => {
+    it('applies only one rule for a', () => {
       const dep = {
         depName: 'a',
       };
       const res = depTypeWorker.getDepConfig(depTypeConfig, dep);
       expect(res.x).toBe(2);
       expect(res.y).toBeUndefined();
-      expect(res.packages).toBeUndefined();
+      expect(res.packageRules).toBeUndefined();
+    });
+    it('applies only one rule for b', () => {
+      const dep = {
+        depName: 'b',
+      };
+      const res = depTypeWorker.getDepConfig(depTypeConfig, dep);
+      expect(res.x).toBe(2);
+      expect(res.y).toBeUndefined();
+      expect(res.packageRules).toBeUndefined();
     });
     it('applies the second rule', () => {
       const dep = {
@@ -78,7 +89,34 @@ describe('lib/workers/dep-type/index', () => {
       const res = depTypeWorker.getDepConfig(depTypeConfig, dep);
       expect(res.x).toBeUndefined();
       expect(res.y).toBe(2);
-      expect(res.packages).toBeUndefined();
+      expect(res.packageRules).toBeUndefined();
+    });
+    it('applies the second second rule', () => {
+      const dep = {
+        depName: 'bc',
+      };
+      const res = depTypeWorker.getDepConfig(depTypeConfig, dep);
+      expect(res.x).toBeUndefined();
+      expect(res.y).toBe(2);
+      expect(res.packageRules).toBeUndefined();
+    });
+    it('excludes package name', () => {
+      const dep = {
+        depName: 'aa',
+      };
+      const res = depTypeWorker.getDepConfig(depTypeConfig, dep);
+      expect(res.x).toBeUndefined();
+      expect(res.y).toBeUndefined();
+      expect(res.packageRules).toBeUndefined();
+    });
+    it('excludes package pattern', () => {
+      const dep = {
+        depName: 'bcd',
+      };
+      const res = depTypeWorker.getDepConfig(depTypeConfig, dep);
+      expect(res.x).toBeUndefined();
+      expect(res.y).toBeUndefined();
+      expect(res.packageRules).toBeUndefined();
     });
   });
 });