diff --git a/bitbake/doc/bitbake-user-manual/bitbake-user-manual-ref-variables.rst b/bitbake/doc/bitbake-user-manual/bitbake-user-manual-ref-variables.rst
index 01d4f8d14a..eaaa307960 100644
--- a/bitbake/doc/bitbake-user-manual/bitbake-user-manual-ref-variables.rst
+++ b/bitbake/doc/bitbake-user-manual/bitbake-user-manual-ref-variables.rst
@@ -686,6 +686,13 @@ overview of their function and contents.
       in images is given a higher priority as compared to build tasks to
       ensure that images do not suffer timeouts on loaded systems.
 
+   :term:`BB_TASK_TIMEOUT`
+      Specifies time after which still running tasks will be terminated.
+
+      Time is provided as an integer number of seconds.
+      You can set timeout for specific task using ``BB_TASK_TIMEOUT[do_mytask]``.
+      To remove timeout use an empty value ``BB_TASK_TIMEOUT = ""``.
+
    :term:`BB_TASKHASH`
       Within an executing task, this variable holds the hash of the task as
       returned by the currently enabled signature generator.
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py
index 44d08f5c55..2057dd9415 100644
--- a/bitbake/lib/bb/build.py
+++ b/bitbake/lib/bb/build.py
@@ -17,6 +17,7 @@ import sys
 import logging
 import glob
 import itertools
+import multiprocessing
 import time
 import re
 import stat
@@ -594,7 +595,7 @@ def _task_data(fn, task, d):
     bb.data.expandKeys(localdata)
     return localdata
 
-def _exec_task(fn, task, d, quieterr):
+def __exec_task(fn, task, d, quieterr):
     """Execute a BB 'task'
 
     Execution of a task involves a bit more setup than executing a function,
@@ -761,6 +762,46 @@ def _exec_task(fn, task, d, quieterr):
 
     return 0
 
+def get_task_timeout(d, task):
+    # task specific timeout
+    timeout = d.getVarFlag("BB_TASK_TIMEOUT", task)
+
+    if timeout is None:
+        # any task timeout
+        timeout = d.getVar("BB_TASK_TIMEOUT")
+
+    if timeout is None or timeout == "":
+        return None
+    else:
+        try:
+            return int(timeout)
+        except ValueError as e:
+            raise ValueError("invalid `BB_TASK_TIMEOUT` value '%s'" % timeout)
+
+def _exec_task(fn, task, d, quieterr):
+    """Intermediate function between exec_task and __exec_task, to support task timeouts."""
+
+    def targetFunc(func):
+        def inner(*args, **kwargs):
+            sys.exit(func(*args, **kwargs))
+
+        return inner
+
+    try:
+        timeout = get_task_timeout(d, task)
+    except ValueError as e:
+        logger.error("%s: %s" % (d.getVar("PF"), e.args[0]))
+        return 1
+
+    task_proc = multiprocessing.Process(target=targetFunc(__exec_task), args=(fn, task, d, quieterr))
+    task_proc.start()
+    task_proc.join(timeout)
+    if task_proc.exitcode is None:
+        logger.error("timeout exceeded (%s s)" % (str(timeout)))
+        return 1
+    else:
+        return task_proc.exitcode
+
 def exec_task(fn, task, d, profile = False):
     try:
         quieterr = False
