diff --git a/kwant/_common.py b/kwant/_common.py
index 71b4f7826e3d963278a72b199fc9827227fee141..e4623b8d09c0d8a307fcab8dff2b6571fb4112c3 100644
--- a/kwant/_common.py
+++ b/kwant/_common.py
@@ -12,6 +12,7 @@ import numbers
 import inspect
 import warnings
 import importlib
+import functools
 from contextlib import contextmanager
 
 __all__ = ['KwantDeprecationWarning', 'UserCodeError']
@@ -41,6 +42,46 @@ class UserCodeError(Exception):
     pass
 
 
+def deprecate_parameter(parameter_name, version=None, help=None,
+                        stacklevel=3):
+    """Trigger a deprecation warning if the wrapped function is called
+       with the provided parameter."""
+
+    message = ("The '{}' parameter has been deprecated since version {} -- {}"
+               .format(parameter_name, version, help))
+
+    def warn():
+        warnings.warn(message, KwantDeprecationWarning,
+                      stacklevel=stacklevel)
+
+    def wrapper(f=None):
+
+        # Instead of being used as a decorator, can be called with
+        # no arguments to just raise the warning.
+        if f is None:
+            warn()
+            return
+
+        sig = inspect.signature(f)
+
+        @functools.wraps(f)
+        def inner(*args, **kwargs):
+            # If the named argument is truthy
+            if sig.bind(*args, **kwargs).arguments.get(parameter_name):
+                warn()
+            return f(*args, **kwargs)
+
+        return inner
+
+    return wrapper
+
+
+# Deprecation for 'args' parameter; defined once to minimize boilerplate,
+# as this parameter is present all over Kwant.
+deprecate_args = deprecate_parameter('args', version=1.4, help=
+    "Instead, provide named parameters as a dictionary via 'params'.")
+
+
 def interleave(seq):
     """Return an iterator that yields pairs of elements from a sequence.