How to flatten a non-planar face to a targeted plane?
What @Denis suggested is good, I mean, it can be convenient sometimes with the help of view align. Besides, there are also other ways to do so:

Method 1:


Enable Snap, set Snap Element to Vertex.
Hold Shift and click on Edge Select button.
Use Normal as the Transform coordinate.
Use Active Element as the pivot center.
First select the vertex you want to move, then the edge that contains any two vertices on the target plane. Then R Y Y, then rotate until it snapped on another vertex on the same plane.




Method 2:


Temporarily triangulate the face.
Use Active Element as the pivot center.
Keep the target triangle selected, which is coplanar with that plane, then S Z Z 0.
Select the two triangles, press F to convert them back to quad. 




Method 3:


Snap the vertex that you want to move to counter vertex.
Keep it activated, then G G to slide it along one edge, press C once or holding Alt to disable Clamp.
Repeat last step on another edge.




Method 4:

This is sort of similar to Denis's answer, but keeping current point of view unchanged (needed sometimes).


Select three vertices, create a new coordinate system based on current selection (or simply press Ctrl Alt Spacebar), and use it as current transform orientation.
Use Active Element as the pivot center.
First select the vertex you want to move, then select any one of the rest vertices, then S Z Z 0.




Method 5:

This is really a one-stop solution by using a script/addon coded by nirenyang, a friend from local community. After being requested, he made this for us, also posted on BA.

Here is my translated version of his script:


bl_info = {
    "name": "Coplanar by 3 Verts",
    "author": "NirenYang[BlenderCN]",
    "version": (0, 1),
    "blender": (2, 75, 5),
    "location": "3d view - toolbar",
    "description": "Make vertices coplanar using a plane defined by the first/last three selected verts.",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "mesh",
}

import bpy
import bmesh
from mathutils.geometry import intersect_line_plane, distance_point_to_plane, normal

enum_ref = [( 'first', 'First', 'Defined by the first three selected verts' ),
            ( 'last', 'Last', 'Defined by the last three selected verts' )]
class MESH_OT_3points_flat_trim(bpy.types.Operator):
    """
    Manually pick three vertices to define the reference plane
    """
    bl_idname = 'mesh.3points_flat_trim'
    bl_label = 'Coplanar by 3 Verts'
    bl_options = {'REGISTER', 'UNDO'}

ref_order = bpy.props.EnumProperty(name='Refferece Plane', description='Use the first/last three selected vertices to define the reference plane', items=enum_ref, default="last")
filter_distance = bpy.props.FloatProperty(name='Filter Distance', description='Only affects vertices further than this distance', default=0.0, precision=3, min=0.0)


@classmethod
def poll(cls, context):
    obj = context.active_object
    return (obj and obj.type == 'MESH')

def execute(self, context):
    C = context
    D = bpy.data
    ob = C.active_object

    #if bpy.app.debug != True:
    #    bpy.app.debug = True
    #    if C.active_object.show_extra_indices != True:
    #        C.active_object.show_extra_indices = True

    if ob.mode == 'OBJECT':
        me = C.object.data
        bm = bmesh.new()
        bm.from_mesh(me)
    else:
        obj = C.edit_object
        me = obj.data
        bm = bmesh.from_edit_mesh(me)

    bm.select_history.validate()
    if len(bm.select_history) &lt; 3:
        self.report({'INFO'}, 'Pick three vertices first')
        return {'CANCELLED'}

    points3Index = []
    points3 = []
    _ordering = bm.select_history if self.ref_order=="first" else list(bm.select_history)[::-1]
    for i in _ordering:
        if len(points3) &gt;= 3:
            break
        elif isinstance(i, bmesh.types.BMVert):
            points3.append(i.co)
            points3Index.append(i.index)
    print(points3Index)
    if len(points3) &lt; 3:
        self.report({'INFO'}, 'at least three vertices are needed to be selected')
        return {'CANCELLED'}


    points3Normal = normal(*points3)
    for v in bm.verts:
        if v.select and v.index not in points3Index:
            _move = True
            if self.filter_distance &gt; 0.0:
                _move = abs(distance_point_to_plane(v.co, points3[0], points3Normal)) &lt; self.filter_distance
            if _move == True:
                v.co = intersect_line_plane(v.co, v.co+points3Normal, points3[0], points3Normal)

    if ob.mode == 'OBJECT':
        bm.to_mesh(me)
        bm.free()
    else:
        bmesh.update_edit_mesh(me, True)

    return {'FINISHED'}

def menu_func_MESH_OT_3points_flat_trim(self, context):
    self.layout.operator(MESH_OT_3points_flat_trim.bl_idname,
                        text=MESH_OT_3points_flat_trim.bl_label)

def register():   
    bpy.utils.register_class(MESH_OT_3points_flat_trim) 
    bpy.types.VIEW3D_PT_tools_meshedit.append(menu_func_MESH_OT_3points_flat_trim)

def unregister():
    bpy.types.VIEW3D_PT_tools_meshedit.remove(menu_func_MESH_OT_3points_flat_trim)
    bpy.utils.unregister_class(MESH_OT_3points_flat_trim)

if __name__ == "__main__":
    register()