diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a5e005c533cb6be16adc8251e7503ca47d94abf1..c14f4d1059d3044aa1868b7001c883f0d32dc698 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -11,6 +11,13 @@ bandit:
   - apt-get -qqy install --no-install-recommends python3-bandit
   - bandit -r ./libmat2 --format txt --skip B101,B404,B603,B405,B314
 
+pylint:
+  stage: linting
+  script:
+  - apt-get -qqy update
+  - apt-get -qqy install --no-install-recommends pylint3 python3-mutagen python3-gi-cairo gir1.2-poppler-0.18 gir1.2-gdkpixbuf-2.0
+  - pylint3 --extension-pkg-whitelist=cairo,gi ./libmat2
+
 pyflakes:
   stage: linting
   script:
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000000000000000000000000000000000000..1f3dc232b61af8132b3a58b83e1025438be137a6
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,16 @@
+[FORMAT]
+good-names=e,f,i,x,s
+max-locals=20
+
+[MESSAGES CONTROL]
+disable=
+    fixme,
+    invalid-name,
+    missing-docstring,
+    protected-access,
+		abstract-method,
+		wrong-import-position,
+		catching-non-exception,
+		cell-var-from-loop,
+		locally-disabled,
+		invalid-sequence-index,  # pylint doesn't like things like `Tuple[int, bytes]` in type annotation