diff --git a/README.md b/README.md
index a64ca450f..d8ca90eb9 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,7 @@ Validator                               | Description
 **isVAT(str, countryCode)**             | check if the string is a [valid VAT number][VAT Number] if validation is available for the given country code matching [ISO 3166-1 alpha-2][ISO 3166-1 alpha-2]. <br/><br/>`countryCode` is one of `['AL', 'AR', 'AT', 'AU', 'BE', 'BG', 'BO', 'BR', 'BY', 'CA', 'CH', 'CL', 'CO', 'CR', 'CY', 'CZ', 'DE', 'DK', 'DO', 'EC', 'EE', 'EL', 'ES', 'FI', 'FR', 'GB', 'GT', 'HN', 'HR', 'HU', 'ID', 'IE', 'IL', 'IN', 'IS', 'IT', 'KZ', 'LT', 'LU', 'LV', 'MK', 'MT', 'MX', 'NG', 'NI', 'NL', 'NO', 'NZ', 'PA', 'PE', 'PH', 'PL', 'PT', 'PY', 'RO', 'RS', 'RU', 'SA', 'SE', 'SI', 'SK', 'SM', 'SV', 'TR', 'UA', 'UY', 'UZ', 'VE']`.
 **isWhitelisted(str, chars)**           | check if the string consists only of characters that appear in the whitelist `chars`.
 **matches(str, pattern [, modifiers])** | check if the string matches the pattern.<br/><br/>Either `matches('foo', /foo/i)` or `matches('foo', 'foo', 'i')`.
+**isCPF(str)**                          | check if the string follows the rules defined by the Brazilian Federal Revenue Service for CPF verification digit calculation.
 
 ## Sanitizers
 
diff --git a/src/index.js b/src/index.js
index c47674595..20baffb54 100644
--- a/src/index.js
+++ b/src/index.js
@@ -130,6 +130,8 @@ import isStrongPassword from './lib/isStrongPassword';
 
 import isVAT from './lib/isVAT';
 
+import isCPF from './lib/isCPF';
+
 const version = '13.15.0';
 
 const validator = {
@@ -245,6 +247,7 @@ const validator = {
   isLicensePlate,
   isVAT,
   ibanLocales,
+  isCPF,
 };
 
 export default validator;
diff --git a/src/lib/isCPF.js b/src/lib/isCPF.js
new file mode 100644
index 000000000..d9ddf789f
--- /dev/null
+++ b/src/lib/isCPF.js
@@ -0,0 +1,52 @@
+import assertString from './util/assertString';
+
+const isMask = /[.-]/g;
+const repeatedDigitsRegex = /^(\d)\1{10}$/;
+
+export default function isCPF(cpf) {
+  assertString(cpf);
+
+  let cleanedCPF = String(cpf);
+
+  if (isMask.test(cleanedCPF)) {
+    cleanedCPF = cleanedCPF.replace(isMask, '');
+  }
+
+  if (cleanedCPF.length !== 11) return false;
+  if (repeatedDigitsRegex.test(cleanedCPF)) return false;
+
+  const paramD1 = {
+    10: 0, 9: 1, 8: 2, 7: 3, 6: 4, 5: 5, 4: 6, 3: 7, 2: 8,
+  };
+  const paramD2 = {
+    11: 0, 10: 1, 9: 2, 8: 3, 7: 4, 6: 5, 5: 6, 4: 7, 3: 8, 2: 9,
+  };
+  let firstNineCharacters = cleanedCPF.slice(0, 9);
+  let d1 = 0;
+  let d2 = 0;
+
+  for (let i = 10; i >= 2; i--) {
+    if (Number.isNaN(Number(firstNineCharacters[paramD1[i]]))) return false;
+    d1 += Number(firstNineCharacters[paramD1[i]]) * i;
+  }
+
+  if (d1 % 11 < 2) {
+    d1 = 0;
+  } else {
+    d1 = 11 - (d1 % 11);
+  }
+
+  firstNineCharacters += String(d1);
+
+  for (let i = 11; i >= 2; i--) {
+    d2 += Number(firstNineCharacters[paramD2[i]]) * i;
+  }
+
+  if (d2 % 11 < 2) {
+    d2 = 0;
+  } else {
+    d2 = 11 - (d2 % 11);
+  }
+
+  return cleanedCPF.slice(-2) === `${d1}${d2}`;
+}
diff --git a/test/validators.test.js b/test/validators.test.js
index d6e948a41..e8dcf2b00 100644
--- a/test/validators.test.js
+++ b/test/validators.test.js
@@ -15440,4 +15440,63 @@ describe('Validators', () => {
       ],
     });
   });
+  it('should validate a CPF', () => {
+    test({
+      validator: 'isCPF',
+      valid: [
+        '157.099.548-61',
+        '55734947598',
+        '601.425.558-35',
+        '54945762139',
+        '367.181.238-97',
+        '43849941922',
+        '979.893.929-84',
+        '98273014037',
+        '666.030.947-03',
+        '40668005130',
+        '506.999.755-65',
+        '98798876465',
+        '816.611.889-07',
+        '52991780002',
+        '037.039.807-61',
+        '62281573370',
+        '055.751.255-72',
+        '03085770860',
+        '286.860.021-29',
+        '24234579793',
+      ],
+      invalid: [
+        '296.231.440-69',
+        '62424843039',
+        '477.887.094-96',
+        '41526890821',
+        '861.803.242-00',
+        '57751926579',
+        '034.928.141-63',
+        '66437339822',
+        '178.714.111-57',
+        '27507501358',
+        '769.259.949-19',
+        '43661169739',
+        '646.438.057-95',
+        '49403410474',
+        '113.512.907-25',
+        '81322401108',
+        '458.825.895-23',
+        '92472311425',
+        '585.251.576-48',
+        '00002283074',
+        '796.940.600-52',
+        '08228682581',
+        '906.765.489-12',
+        '31437427245',
+        '045.504.051-45',
+        '21383151886',
+        '519.213.751-90',
+        '06712261581',
+        '884.593.736-07',
+        '42188048376',
+      ],
+    });
+  });
 });