Index: django/newforms/util.py
===================================================================
--- django/newforms/util.py	(revision 7229)
+++ django/newforms/util.py	(working copy)
@@ -50,11 +50,12 @@
         return repr([force_unicode(e) for e in self])
 
 class ValidationError(Exception):
-    def __init__(self, message):
+    def __init__(self, message, field_name=None):
         """
         ValidationError can be passed any object that can be printed (usually
         a string) or a list of objects.
         """
+        self.field_name = field_name
         if isinstance(message, list):
             self.messages = ErrorList([smart_unicode(msg) for msg in message])
         else:
Index: django/newforms/forms.py
===================================================================
--- django/newforms/forms.py	(revision 7229)
+++ django/newforms/forms.py	(working copy)
@@ -238,7 +238,7 @@
         try:
             self.cleaned_data = self.clean()
         except ValidationError, e:
-            self._errors[NON_FIELD_ERRORS] = e.messages
+            self._errors[e.field_name or NON_FIELD_ERRORS] = e.messages
         if self._errors:
             delattr(self, 'cleaned_data')
 
Index: tests/regressiontests/forms/forms.py
===================================================================
--- tests/regressiontests/forms/forms.py	(revision 7229)
+++ tests/regressiontests/forms/forms.py	(working copy)
@@ -611,8 +611,11 @@
 
 Another way of doing multiple-field validation is by implementing the
 Form's clean() method. If you do this, any ValidationError raised by that
-method will not be associated with a particular field; it will have a
-special-case association with the field named '__all__'.
+method either will not be associated with a particular field
+and will have a special-case association with the field named '__all__'; 
+or if you specify the invalid field explicitly by passing the 'field_name'
+parameter to the error constructor, it will be associated with the field in
+similar manner to clean_XXX().
 Note that in Form.clean(), you have access to self.cleaned_data, a dictionary of
 all the fields/values that have *not* raised a ValidationError. Also note
 Form.clean() is required to return a dictionary of all clean data.
@@ -652,6 +655,40 @@
 {}
 >>> f.cleaned_data
 {'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
+>>> class UserRegistration(Form):
+...    username = CharField(max_length=10)
+...    password1 = CharField(widget=PasswordInput)
+...    password2 = CharField(widget=PasswordInput)
+...    def clean(self):
+...        if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
+...            raise ValidationError(u'Please make sure your passwords match.', field_name = 'password2')
+...        return self.cleaned_data
+>>> f = UserRegistration(auto_id=False)
+>>> f.errors
+{}
+>>> f = UserRegistration({}, auto_id=False)
+>>> print f.as_table()
+<tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr>
+<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr>
+<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>
+>>> f.errors
+{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
+>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
+>>> f.errors
+{'password2': [u'Please make sure your passwords match.']}
+>>> print f.as_table()
+<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
+<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
+<tr><th>Password2:</th><td><ul class="errorlist"><li>Please make sure your passwords match.</li></ul><input type="password" name="password2" value="bar" /></td></tr>
+>>> print f.as_ul()
+<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
+<li>Password1: <input type="password" name="password1" value="foo" /></li>
+<li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul>Password2: <input type="password" name="password2" value="bar" /></li>
+>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
+>>> f.errors
+{}
+>>> f.cleaned_data
+{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
 
 # Dynamic construction ########################################################
 
